summaryrefslogtreecommitdiffstats
path: root/sys/geom/nop
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/geom/nop
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/geom/nop')
-rw-r--r--sys/geom/nop/g_nop.c13
-rw-r--r--sys/geom/nop/g_nop.h1
2 files changed, 12 insertions, 2 deletions
diff --git a/sys/geom/nop/g_nop.c b/sys/geom/nop/g_nop.c
index a1a1ad1..bd72d78 100644
--- a/sys/geom/nop/g_nop.c
+++ b/sys/geom/nop/g_nop.c
@@ -107,6 +107,7 @@ g_nop_start(struct bio *bp)
gp = bp->bio_to->geom;
sc = gp->softc;
G_NOP_LOGREQ(bp, "Request received.");
+ mtx_lock(&sc->sc_lock);
switch (bp->bio_cmd) {
case BIO_READ:
sc->sc_reads++;
@@ -119,6 +120,7 @@ g_nop_start(struct bio *bp)
failprob = sc->sc_wfailprob;
break;
}
+ mtx_unlock(&sc->sc_lock);
if (failprob > 0) {
u_int rval;
@@ -224,6 +226,7 @@ g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp,
sc->sc_writes = 0;
sc->sc_readbytes = 0;
sc->sc_wrotebytes = 0;
+ mtx_init(&sc->sc_lock, "gnop lock", NULL, MTX_DEF);
gp->softc = sc;
gp->start = g_nop_start;
gp->orphan = g_nop_orphan;
@@ -232,10 +235,12 @@ g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp,
gp->dumpconf = g_nop_dumpconf;
newpp = g_new_providerf(gp, "%s", gp->name);
+ newpp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE;
newpp->mediasize = size;
newpp->sectorsize = secsize;
cp = g_new_consumer(gp);
+ cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE;
error = g_attach(cp, pp);
if (error != 0) {
gctl_error(req, "Cannot attach to provider %s.", pp->name);
@@ -251,6 +256,7 @@ fail:
g_detach(cp);
g_destroy_consumer(cp);
g_destroy_provider(newpp);
+ mtx_destroy(&sc->sc_lock);
g_free(gp->softc);
g_destroy_geom(gp);
return (error);
@@ -259,10 +265,12 @@ fail:
static int
g_nop_destroy(struct g_geom *gp, boolean_t force)
{
+ struct g_nop_softc *sc;
struct g_provider *pp;
g_topology_assert();
- if (gp->softc == NULL)
+ sc = gp->softc;
+ if (sc == NULL)
return (ENXIO);
pp = LIST_FIRST(&gp->provider);
if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) {
@@ -277,8 +285,9 @@ g_nop_destroy(struct g_geom *gp, boolean_t force)
} else {
G_NOP_DEBUG(0, "Device %s removed.", gp->name);
}
- g_free(gp->softc);
gp->softc = NULL;
+ mtx_destroy(&sc->sc_lock);
+ g_free(sc);
g_wither_geom(gp, ENXIO);
return (0);
diff --git a/sys/geom/nop/g_nop.h b/sys/geom/nop/g_nop.h
index da555ec..3e37c05 100644
--- a/sys/geom/nop/g_nop.h
+++ b/sys/geom/nop/g_nop.h
@@ -65,6 +65,7 @@ struct g_nop_softc {
uintmax_t sc_writes;
uintmax_t sc_readbytes;
uintmax_t sc_wrotebytes;
+ struct mtx sc_lock;
};
#endif /* _KERNEL */
OpenPOWER on IntegriCloud