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
This commit is contained in:
parent
bf71eaacf1
commit
dddd1d537a
@ -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 @@ g_eli_create(struct gctl_req *req, struct g_class *mp, struct g_provider *bpp,
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user