Date: Thu, 21 Oct 2010 19:44:28 +0000 (UTC) From: Pawel Jakub Dawidek <pjd@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r214163 - head/sys/geom/eli Message-ID: <201010211944.o9LJiSnk001707@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: pjd Date: Thu Oct 21 19:44:28 2010 New Revision: 214163 URL: http://svn.freebsd.org/changeset/base/214163 Log: Free opencrypto sessions on suspend, as they also might keep encryption keys. Modified: head/sys/geom/eli/g_eli.c head/sys/geom/eli/g_eli.h Modified: head/sys/geom/eli/g_eli.c ============================================================================== --- head/sys/geom/eli/g_eli.c Thu Oct 21 19:30:55 2010 (r214162) +++ head/sys/geom/eli/g_eli.c Thu Oct 21 19:44:28 2010 (r214163) @@ -314,6 +314,69 @@ g_eli_start(struct bio *bp) } } +static int +g_eli_newsession(struct g_eli_worker *wr) +{ + struct g_eli_softc *sc; + struct cryptoini crie, cria; + int error; + + sc = wr->w_softc; + + bzero(&crie, sizeof(crie)); + crie.cri_alg = sc->sc_ealgo; + crie.cri_klen = sc->sc_ekeylen; + if (sc->sc_ealgo == CRYPTO_AES_XTS) + crie.cri_klen <<= 1; + crie.cri_key = sc->sc_ekeys[0]; + if (sc->sc_flags & G_ELI_FLAG_AUTH) { + bzero(&cria, sizeof(cria)); + cria.cri_alg = sc->sc_aalgo; + cria.cri_klen = sc->sc_akeylen; + cria.cri_key = sc->sc_akey; + crie.cri_next = &cria; + } + + switch (sc->sc_crypto) { + case G_ELI_CRYPTO_SW: + error = crypto_newsession(&wr->w_sid, &crie, + CRYPTOCAP_F_SOFTWARE); + break; + case G_ELI_CRYPTO_HW: + error = crypto_newsession(&wr->w_sid, &crie, + CRYPTOCAP_F_HARDWARE); + break; + case G_ELI_CRYPTO_UNKNOWN: + error = crypto_newsession(&wr->w_sid, &crie, + CRYPTOCAP_F_HARDWARE); + if (error == 0) { + mtx_lock(&sc->sc_queue_mtx); + if (sc->sc_crypto == G_ELI_CRYPTO_UNKNOWN) + sc->sc_crypto = G_ELI_CRYPTO_HW; + mtx_unlock(&sc->sc_queue_mtx); + } else { + error = crypto_newsession(&wr->w_sid, &crie, + CRYPTOCAP_F_SOFTWARE); + mtx_lock(&sc->sc_queue_mtx); + if (sc->sc_crypto == G_ELI_CRYPTO_UNKNOWN) + sc->sc_crypto = G_ELI_CRYPTO_SW; + mtx_unlock(&sc->sc_queue_mtx); + } + break; + default: + panic("%s: invalid condition", __func__); + } + + return (error); +} + +static void +g_eli_freesession(struct g_eli_worker *wr) +{ + + crypto_freesession(wr->w_sid); +} + static void g_eli_cancel(struct g_eli_softc *sc) { @@ -361,6 +424,7 @@ 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; @@ -388,7 +452,7 @@ again: if (sc->sc_flags & G_ELI_FLAG_DESTROY) { g_eli_cancel(sc); LIST_REMOVE(wr, w_next); - crypto_freesession(wr->w_sid); + g_eli_freesession(wr); free(wr, M_ELI); G_ELI_DEBUG(1, "Thread %s exiting.", curthread->td_proc->p_comm); @@ -411,12 +475,21 @@ again: * Suspend requested, mark the worker as * suspended and go to sleep. */ - wr->w_active = 0; + if (wr->w_active) { + g_eli_freesession(wr); + wr->w_active = FALSE; + } wakeup(&sc->sc_workers); msleep(sc, &sc->sc_queue_mtx, PRIBIO, "geli:suspend", 0); - if (!(sc->sc_flags & G_ELI_FLAG_SUSPEND)) - wr->w_active = 1; + if (!wr->w_active && + !(sc->sc_flags & G_ELI_FLAG_SUSPEND)) { + error = g_eli_newsession(wr); + KASSERT(error == 0, + ("g_eli_newsession() failed on resume (error=%d)", + error)); + wr->w_active = TRUE; + } goto again; } msleep(sc, &sc->sc_queue_mtx, PDROP, "geli:w", 0); @@ -630,7 +703,6 @@ g_eli_create(struct gctl_req *req, struc struct g_geom *gp; struct g_provider *pp; struct g_consumer *cp; - struct cryptoini crie, cria; u_int i, threads; int error; @@ -658,7 +730,7 @@ g_eli_create(struct gctl_req *req, struc gp->access = g_std_access; sc->sc_inflight = 0; - sc->sc_crypto = G_ELI_CRYPTO_SW; + sc->sc_crypto = G_ELI_CRYPTO_UNKNOWN; sc->sc_flags = md->md_flags; /* Backward compatibility. */ if (md->md_version < 4) @@ -772,20 +844,6 @@ g_eli_create(struct gctl_req *req, struc LIST_INIT(&sc->sc_workers); - bzero(&crie, sizeof(crie)); - crie.cri_alg = sc->sc_ealgo; - crie.cri_klen = sc->sc_ekeylen; - if (sc->sc_ealgo == CRYPTO_AES_XTS) - crie.cri_klen <<= 1; - crie.cri_key = sc->sc_ekeys[0]; - if (sc->sc_flags & G_ELI_FLAG_AUTH) { - bzero(&cria, sizeof(cria)); - cria.cri_alg = sc->sc_aalgo; - cria.cri_klen = sc->sc_akeylen; - cria.cri_key = sc->sc_akey; - crie.cri_next = &cria; - } - threads = g_eli_threads; if (threads == 0) threads = mp_ncpus; @@ -805,20 +863,7 @@ g_eli_create(struct gctl_req *req, struc wr->w_number = i; wr->w_active = TRUE; - /* - * If this is the first pass, try to get hardware support. - * Use software cryptography, if we cannot get it. - */ - if (LIST_EMPTY(&sc->sc_workers)) { - error = crypto_newsession(&wr->w_sid, &crie, - CRYPTOCAP_F_HARDWARE); - if (error == 0) - sc->sc_crypto = G_ELI_CRYPTO_HW; - } - if (sc->sc_crypto == G_ELI_CRYPTO_SW) { - error = crypto_newsession(&wr->w_sid, &crie, - CRYPTOCAP_F_SOFTWARE); - } + error = g_eli_newsession(wr); if (error != 0) { free(wr, M_ELI); if (req != NULL) { @@ -834,7 +879,7 @@ g_eli_create(struct gctl_req *req, struc error = kproc_create(g_eli_worker, wr, &wr->w_proc, 0, 0, "g_eli[%u] %s", i, bpp->name); if (error != 0) { - crypto_freesession(wr->w_sid); + g_eli_freesession(wr); free(wr, M_ELI); if (req != NULL) { gctl_error(req, "Cannot create kernel thread " Modified: head/sys/geom/eli/g_eli.h ============================================================================== --- head/sys/geom/eli/g_eli.h Thu Oct 21 19:30:55 2010 (r214162) +++ head/sys/geom/eli/g_eli.h Thu Oct 21 19:44:28 2010 (r214163) @@ -113,6 +113,7 @@ extern int g_eli_debug; extern u_int g_eli_overwrites; extern u_int g_eli_batch; +#define G_ELI_CRYPTO_UNKNOWN 0 #define G_ELI_CRYPTO_HW 1 #define G_ELI_CRYPTO_SW 2
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201010211944.o9LJiSnk001707>