summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2005-08-17 15:25:57 +0000
committerpjd <pjd@FreeBSD.org>2005-08-17 15:25:57 +0000
commit653998193b884a46bb9d9e4c115453e92f613714 (patch)
tree81ad5fd2a527be451e544b9634d782716ef6c53e
parent768e62bfca3ccff1f1d051fdf1299d5fd762dd35 (diff)
downloadFreeBSD-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.c151
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;
OpenPOWER on IntegriCloud