diff options
author | pjd <pjd@FreeBSD.org> | 2005-08-17 15:25:57 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2005-08-17 15:25:57 +0000 |
commit | 653998193b884a46bb9d9e4c115453e92f613714 (patch) | |
tree | 81ad5fd2a527be451e544b9634d782716ef6c53e | |
parent | 768e62bfca3ccff1f1d051fdf1299d5fd762dd35 (diff) | |
download | FreeBSD-src-653998193b884a46bb9d9e4c115453e92f613714.zip FreeBSD-src-653998193b884a46bb9d9e4c115453e92f613714.tar.gz |
Always run dedicated kernel thread (even when we have hardware support).
There is no performance impact, but allows to allocate memory with
M_WAITOK flag.
As a side effect this simplify code a bit.
MFC after: 3 days
-rw-r--r-- | sys/geom/eli/g_eli.c | 151 |
1 files changed, 37 insertions, 114 deletions
diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c index 0a0bef8..30dcba3 100644 --- a/sys/geom/eli/g_eli.c +++ b/sys/geom/eli/g_eli.c @@ -77,7 +77,7 @@ static int g_eli_do_taste = 0; static int g_eli_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp); -static int g_eli_crypto_run(struct g_eli_worker *wr, struct bio *bp); +static void g_eli_crypto_run(struct g_eli_worker *wr, struct bio *bp); static g_taste_t g_eli_taste; static g_dumpconf_t g_eli_dumpconf; @@ -143,7 +143,6 @@ g_eli_read_done(struct bio *bp) { struct g_eli_softc *sc; struct bio *pbp; - int error; G_ELI_LOGREQ(2, bp, "Request done."); pbp = bp->bio_parent; @@ -157,28 +156,10 @@ g_eli_read_done(struct bio *bp) return; } sc = pbp->bio_to->geom->softc; - /* - * If we have hardware acceleration we can call g_eli_crypto_run() - * directly. If not, put it on the queue and wakeup worker thread, - * which will do the work for us, so we don't slow down g_up path. - */ - if (sc->sc_crypto == G_ELI_CRYPTO_HW) { - struct g_eli_worker *wr; - - wr = LIST_FIRST(&sc->sc_workers); - error = g_eli_crypto_run(wr, pbp); - if (error != 0) { - G_ELI_LOGREQ(0, pbp, - "g_eli_crypto_run() failed (error=%d).", error); - pbp->bio_completed = 0; - g_io_deliver(pbp, error); - } - } else { - mtx_lock(&sc->sc_queue_mtx); - bioq_insert_tail(&sc->sc_queue, pbp); - mtx_unlock(&sc->sc_queue_mtx); - wakeup(sc); - } + mtx_lock(&sc->sc_queue_mtx); + bioq_insert_tail(&sc->sc_queue, pbp); + mtx_unlock(&sc->sc_queue_mtx); + wakeup(sc); } /* @@ -385,33 +366,11 @@ g_eli_start(struct bio *bp) */ g_io_request(cbp, cp); } else /* if (bp->bio_cmd == BIO_WRITE) */ { - struct g_eli_worker *wr; - int error; - bp->bio_driver1 = cbp; - wr = LIST_FIRST(&sc->sc_workers); - /* - * If we have hardware acceleration we can call - * g_eli_crypto_run() directly. If not, put it on the queue and - * wakeup worker thread, which will do the work for us, so we - * don't slow down g_down path. - */ - if (sc->sc_crypto == G_ELI_CRYPTO_HW) { - error = g_eli_crypto_run(wr, bp); - if (error != 0) { - G_ELI_LOGREQ(0, bp, - "g_eli_crypto_run() failed (error=%d).", - error); - g_destroy_bio(cbp); - bp->bio_completed = 0; - g_io_deliver(bp, error); - } - } else { - mtx_lock(&sc->sc_queue_mtx); - bioq_insert_tail(&sc->sc_queue, bp); - mtx_unlock(&sc->sc_queue_mtx); - wakeup(sc); - } + mtx_lock(&sc->sc_queue_mtx); + bioq_insert_tail(&sc->sc_queue, bp); + mtx_unlock(&sc->sc_queue_mtx); + wakeup(sc); } } @@ -427,7 +386,6 @@ g_eli_worker(void *arg) struct g_eli_softc *sc; struct g_eli_worker *wr; struct bio *bp; - int error; wr = arg; sc = wr->w_softc; @@ -456,18 +414,7 @@ g_eli_worker(void *arg) continue; } mtx_unlock(&sc->sc_queue_mtx); - error = g_eli_crypto_run(wr, bp); - if (error != 0) { - G_ELI_LOGREQ(0, bp, - "g_eli_crypto_run() failed (error=%d).", error); - if (bp->bio_cmd == BIO_WRITE) { - g_destroy_bio(bp->bio_driver1); - bp->bio_driver1 = NULL; - } - bp->bio_driver2 = NULL; - bp->bio_completed = 0; - g_io_deliver(bp, error); - } + g_eli_crypto_run(wr, bp); } } @@ -492,7 +439,7 @@ g_eli_crypto_ivgen(struct g_eli_softc *sc, off_t offset, u_char *iv, * This is the main function responsible for cryptography (ie. communication * with crypto(9) subsystem). */ -static int +static void g_eli_crypto_run(struct g_eli_worker *wr, struct bio *bp) { struct g_eli_softc *sc; @@ -529,9 +476,7 @@ g_eli_crypto_run(struct g_eli_worker *wr, struct bio *bp) */ if (bp->bio_cmd == BIO_WRITE) size += bp->bio_length; - p = malloc(size, M_ELI, M_NOWAIT); - if (p == NULL) - return (ENOMEM); + p = malloc(size, M_ELI, M_WAITOK); bp->bio_inbed = 0; bp->bio_children = nsec; @@ -593,7 +538,6 @@ g_eli_crypto_run(struct g_eli_worker *wr, struct bio *bp) } if (bp->bio_error == 0) bp->bio_error = error; - return (0); } int @@ -810,14 +754,11 @@ g_eli_create(struct gctl_req *req, struct g_class *mp, struct g_provider *bpp, */ if (i == 0) { error = crypto_newsession(&wr->w_sid, &cri, 1); - if (error == 0) { + if (error == 0) sc->sc_crypto = G_ELI_CRYPTO_HW; - wr->w_proc = NULL; - LIST_INSERT_HEAD(&sc->sc_workers, wr, w_next); - break; - } } - error = crypto_newsession(&wr->w_sid, &cri, 0); + if (sc->sc_crypto == G_ELI_CRYPTO_SW) + error = crypto_newsession(&wr->w_sid, &cri, 0); if (error != 0) { free(wr, M_ELI); if (req != NULL) { @@ -841,17 +782,18 @@ g_eli_create(struct gctl_req *req, struct g_class *mp, struct g_provider *bpp, crypto_freesession(wr->w_sid); free(wr, M_ELI); if (req != NULL) { - gctl_error(req, "Cannot create kernel " - "thread for %s (error=%d).", - bpp->name, error); + gctl_error(req, "Cannot create kernel thread " + "for %s (error=%d).", bpp->name, error); } else { - G_ELI_DEBUG(1, "Cannot create kernel " - "thread for %s (error=%d).", - bpp->name, error); + G_ELI_DEBUG(1, "Cannot create kernel thread " + "for %s (error=%d).", bpp->name, error); } goto failed; } LIST_INSERT_HEAD(&sc->sc_workers, wr, w_next); + /* If we have hardware support, one thread is enough. */ + if (sc->sc_crypto == G_ELI_CRYPTO_HW) + break; } /* @@ -872,22 +814,15 @@ g_eli_create(struct gctl_req *req, struct g_class *mp, struct g_provider *bpp, sc->sc_crypto == G_ELI_CRYPTO_SW ? "software" : "hardware"); return (gp); failed: - if (sc->sc_crypto == G_ELI_CRYPTO_SW) { - mtx_lock(&sc->sc_queue_mtx); - sc->sc_flags |= G_ELI_FLAG_DESTROY; - wakeup(sc); - /* - * Wait for kernel threads self destruction. - */ - while (!LIST_EMPTY(&sc->sc_workers)) { - msleep(&sc->sc_workers, &sc->sc_queue_mtx, PRIBIO, - "geli:destroy", 0); - } - } else if (sc->sc_crypto == G_ELI_CRYPTO_HW) { - wr = LIST_FIRST(&sc->sc_workers); - LIST_REMOVE(wr, w_next); - crypto_freesession(wr->w_sid); - free(wr, M_ELI); + mtx_lock(&sc->sc_queue_mtx); + sc->sc_flags |= G_ELI_FLAG_DESTROY; + wakeup(sc); + /* + * Wait for kernel threads self destruction. + */ + while (!LIST_EMPTY(&sc->sc_workers)) { + msleep(&sc->sc_workers, &sc->sc_queue_mtx, PRIBIO, + "geli:destroy", 0); } mtx_destroy(&sc->sc_queue_mtx); if (cp->provider != NULL) { @@ -907,7 +842,6 @@ failed: int g_eli_destroy(struct g_eli_softc *sc, boolean_t force) { - struct g_eli_worker *wr; struct g_geom *gp; struct g_provider *pp; @@ -930,23 +864,12 @@ g_eli_destroy(struct g_eli_softc *sc, boolean_t force) } } - /* - * When we do cryptography in software, we have kernel thread hanging - * around, so we need to destroy it first. - */ - if (sc->sc_crypto == G_ELI_CRYPTO_SW) { - mtx_lock(&sc->sc_queue_mtx); - sc->sc_flags |= G_ELI_FLAG_DESTROY; - wakeup(sc); - while (!LIST_EMPTY(&sc->sc_workers)) { - msleep(&sc->sc_workers, &sc->sc_queue_mtx, PRIBIO, - "geli:destroy", 0); - } - } else /* if (sc->sc_crypto == G_ELI_CRYPTO_HW) */ { - wr = LIST_FIRST(&sc->sc_workers); - LIST_REMOVE(wr, w_next); - crypto_freesession(wr->w_sid); - free(wr, M_ELI); + mtx_lock(&sc->sc_queue_mtx); + sc->sc_flags |= G_ELI_FLAG_DESTROY; + wakeup(sc); + while (!LIST_EMPTY(&sc->sc_workers)) { + msleep(&sc->sc_workers, &sc->sc_queue_mtx, PRIBIO, + "geli:destroy", 0); } mtx_destroy(&sc->sc_queue_mtx); gp->softc = NULL; |