summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2014-01-07 01:32:23 +0000
committerscottl <scottl@FreeBSD.org>2014-01-07 01:32:23 +0000
commit0a34594b9cd7c8b87f719ed058da6be2b756a8e5 (patch)
tree9702de6a6a50f2bb1a6829d66c26686ca7a160cc /sys/kern
parent1bce546983c144fd6d05af45e88abd3186b87b1b (diff)
downloadFreeBSD-src-0a34594b9cd7c8b87f719ed058da6be2b756a8e5.zip
FreeBSD-src-0a34594b9cd7c8b87f719ed058da6be2b756a8e5.tar.gz
MFC Alexander Motin's GEOM direct dispatch work:
r256603: Introduce new function devstat_end_transaction_bio_bt(), adding new argument to specify present time. Use this function to move binuptime() out of lock, substantially reducing lock congestion when slow timecounter is used. r256606: Move g_io_deliver() out of the lock, as required for direct dispatch. Move g_destroy_bio() out too to reduce lock scope even more. r256607: Fix passing uninitialized bio_resid argument to g_trace(). r256610: Add unmapped I/O support to GEOM RAID. r256830: Restore BIO_UNMAPPED and BIO_TRANSIENT_MAPPING in biodonne() when unmapping temporary mapped buffer. That fixes double unmap if biodone() called twice for the same BIO (but with different done methods). r256880: Merge GEOM direct dispatch changes from the projects/camlock branch. When safety requirements are met, it allows to avoid passing I/O requests to GEOM g_up/g_down thread, executing them directly in the caller context. That allows to avoid CPU bottlenecks in g_up/g_down threads, plus avoid several context switches per I/O. r259247: Fix bug introduced at r256607. We have to recalculate bp_resid here since sizes of original and completed requests may differ due to end of media. Testing of the stable/10 merge was done by Netflix, but all of the credit goes to Alexander and iX Systems. Submitted by: mav Sponsored by: iX Systems
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/subr_devstat.c13
-rw-r--r--sys/kern/vfs_bio.c15
2 files changed, 16 insertions, 12 deletions
diff --git a/sys/kern/subr_devstat.c b/sys/kern/subr_devstat.c
index c44ef27..6800ce3 100644
--- a/sys/kern/subr_devstat.c
+++ b/sys/kern/subr_devstat.c
@@ -131,6 +131,7 @@ devstat_new_entry(const void *dev_name,
ds = devstat_alloc();
mtx_lock(&devstat_mutex);
if (unit_number == -1) {
+ ds->unit_number = unit_number;
ds->id = dev_name;
binuptime(&ds->creation_time);
devstat_generation++;
@@ -242,7 +243,7 @@ devstat_remove_entry(struct devstat *ds)
/* Remove this entry from the devstat queue */
atomic_add_acq_int(&ds->sequence1, 1);
- if (ds->id == NULL) {
+ if (ds->unit_number != -1) {
devstat_num_devs--;
STAILQ_REMOVE(devstat_head, ds, devstat, dev_links);
}
@@ -374,6 +375,14 @@ devstat_end_transaction(struct devstat *ds, uint32_t bytes,
void
devstat_end_transaction_bio(struct devstat *ds, struct bio *bp)
{
+
+ devstat_end_transaction_bio_bt(ds, bp, NULL);
+}
+
+void
+devstat_end_transaction_bio_bt(struct devstat *ds, struct bio *bp,
+ struct bintime *now)
+{
devstat_trans_flags flg;
/* sanity check */
@@ -390,7 +399,7 @@ devstat_end_transaction_bio(struct devstat *ds, struct bio *bp)
flg = DEVSTAT_NO_DATA;
devstat_end_transaction(ds, bp->bio_bcount - bp->bio_resid,
- DEVSTAT_TAG_SIMPLE, flg, NULL, &bp->bio_t0);
+ DEVSTAT_TAG_SIMPLE, flg, now, &bp->bio_t0);
DTRACE_DEVSTAT_BIO_DONE();
}
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 3812813..d69bba9 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -3557,15 +3557,15 @@ biodone(struct bio *bp)
struct mtx *mtxp;
void (*done)(struct bio *);
vm_offset_t start, end;
- int transient;
if ((bp->bio_flags & BIO_TRANSIENT_MAPPING) != 0) {
+ bp->bio_flags &= ~BIO_TRANSIENT_MAPPING;
+ bp->bio_flags |= BIO_UNMAPPED;
start = trunc_page((vm_offset_t)bp->bio_data);
end = round_page((vm_offset_t)bp->bio_data + bp->bio_length);
- transient = 1;
- } else {
- transient = 0;
- start = end = 0;
+ pmap_qremove(start, OFF_TO_IDX(end - start));
+ vmem_free(transient_arena, start, end - start);
+ atomic_add_int(&inflight_transient_maps, -1);
}
done = bp->bio_done;
if (done == NULL) {
@@ -3578,11 +3578,6 @@ biodone(struct bio *bp)
bp->bio_flags |= BIO_DONE;
done(bp);
}
- if (transient) {
- pmap_qremove(start, OFF_TO_IDX(end - start));
- vmem_free(transient_arena, start, end - start);
- atomic_add_int(&inflight_transient_maps, -1);
- }
}
/*
OpenPOWER on IntegriCloud