summaryrefslogtreecommitdiffstats
path: root/sys/dev/md
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/dev/md
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/dev/md')
-rw-r--r--sys/dev/md/md.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index f0d1aec..8ae51d1 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -189,6 +189,7 @@ struct md_s {
LIST_ENTRY(md_s) list;
struct bio_queue_head bio_queue;
struct mtx queue_mtx;
+ struct mtx stat_mtx;
struct cdev *dev;
enum md_types type;
off_t mediasize;
@@ -415,8 +416,11 @@ g_md_start(struct bio *bp)
struct md_s *sc;
sc = bp->bio_to->geom->softc;
- if ((bp->bio_cmd == BIO_READ) || (bp->bio_cmd == BIO_WRITE))
+ if ((bp->bio_cmd == BIO_READ) || (bp->bio_cmd == BIO_WRITE)) {
+ mtx_lock(&sc->stat_mtx);
devstat_start_transaction_bio(sc->devstat, bp);
+ mtx_unlock(&sc->stat_mtx);
+ }
mtx_lock(&sc->queue_mtx);
bioq_disksort(&sc->bio_queue, bp);
mtx_unlock(&sc->queue_mtx);
@@ -987,6 +991,7 @@ mdnew(int unit, int *errp, enum md_types type)
sc->type = type;
bioq_init(&sc->bio_queue);
mtx_init(&sc->queue_mtx, "md bio queue", NULL, MTX_DEF);
+ mtx_init(&sc->stat_mtx, "md stat", NULL, MTX_DEF);
sc->unit = unit;
sprintf(sc->name, "md%d", unit);
LIST_INSERT_HEAD(&md_softc_list, sc, list);
@@ -994,6 +999,7 @@ mdnew(int unit, int *errp, enum md_types type)
if (error == 0)
return (sc);
LIST_REMOVE(sc, list);
+ mtx_destroy(&sc->stat_mtx);
mtx_destroy(&sc->queue_mtx);
free_unr(md_uh, sc->unit);
free(sc, M_MD);
@@ -1011,6 +1017,7 @@ mdinit(struct md_s *sc)
gp = g_new_geomf(&g_md_class, "md%d", sc->unit);
gp->softc = sc;
pp = g_new_providerf(gp, "md%d", sc->unit);
+ pp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE;
pp->mediasize = sc->mediasize;
pp->sectorsize = sc->sectorsize;
switch (sc->type) {
@@ -1206,6 +1213,7 @@ mddestroy(struct md_s *sc, struct thread *td)
while (!(sc->flags & MD_EXITING))
msleep(sc->procp, &sc->queue_mtx, PRIBIO, "mddestroy", hz / 10);
mtx_unlock(&sc->queue_mtx);
+ mtx_destroy(&sc->stat_mtx);
mtx_destroy(&sc->queue_mtx);
if (sc->vnode != NULL) {
vn_lock(sc->vnode, LK_EXCLUSIVE | LK_RETRY);
OpenPOWER on IntegriCloud