split the "crypto_mtx" spinlock into 3: one spinlock each for

the incoming and outgoing request queues (which can be dealt with
by hardware accelerators) and an adaptive lock for "all the rest"
(mostly driver configuration, but also some unrelated stuff in
cryptodev.c which should be revisited)
The latter one seems to be uneeded at many places, but for now I've
done simple replacements only, except minor fixes (where
softint_schedule() was called without the lock held)
This commit is contained in:
drochner 2011-05-16 10:27:49 +00:00
parent ee62067b42
commit efd342eb96
3 changed files with 138 additions and 130 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: crypto.c,v 1.39 2011/05/06 21:48:46 drochner Exp $ */
/* $NetBSD: crypto.c,v 1.40 2011/05/16 10:27:49 drochner Exp $ */
/* $FreeBSD: src/sys/opencrypto/crypto.c,v 1.4.2.5 2003/02/26 00:14:05 sam Exp $ */
/* $OpenBSD: crypto.c,v 1.41 2002/07/17 23:52:38 art Exp $ */
@ -53,7 +53,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.39 2011/05/06 21:48:46 drochner Exp $");
__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.40 2011/05/16 10:27:49 drochner Exp $");
#include <sys/param.h>
#include <sys/reboot.h>
@ -70,6 +70,8 @@ __KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.39 2011/05/06 21:48:46 drochner Exp $")
#include <opencrypto/cryptodev.h>
#include <opencrypto/xform.h> /* XXX for M_XDATA */
kmutex_t crypto_q_mtx;
kmutex_t crypto_ret_q_mtx;
kcondvar_t cryptoret_cv;
kmutex_t crypto_mtx;
@ -247,7 +249,9 @@ crypto_init0(void)
{
int error;
mutex_init(&crypto_mtx, MUTEX_DEFAULT, IPL_NET);
mutex_init(&crypto_mtx, MUTEX_DEFAULT, IPL_NONE);
mutex_init(&crypto_q_mtx, MUTEX_DEFAULT, IPL_NET);
mutex_init(&crypto_ret_q_mtx, MUTEX_DEFAULT, IPL_NET);
cv_init(&cryptoret_cv, "crypto_w");
pool_init(&cryptop_pool, sizeof(struct cryptop), 0, 0,
0, "cryptop", NULL, IPL_NET);
@ -303,7 +307,7 @@ crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard)
u_int32_t hid, lid;
int err = EINVAL;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
if (crypto_drivers == NULL)
goto done;
@ -366,7 +370,7 @@ crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard)
}
}
done:
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return err;
}
@ -380,7 +384,7 @@ crypto_freesession(u_int64_t sid)
u_int32_t hid;
int err = 0;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
if (crypto_drivers == NULL) {
err = EINVAL;
@ -415,7 +419,7 @@ crypto_freesession(u_int64_t sid)
memset(&crypto_drivers[hid], 0, sizeof(struct cryptocap));
done:
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return err;
}
@ -431,7 +435,7 @@ crypto_get_driverid(u_int32_t flags)
crypto_init(); /* XXX oh, this is foul! */
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
for (i = 0; i < crypto_drivers_num; i++)
if (crypto_drivers[i].cc_process == NULL &&
(crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0 &&
@ -442,7 +446,7 @@ crypto_get_driverid(u_int32_t flags)
if (i == crypto_drivers_num) {
/* Be careful about wrap-around. */
if (2 * crypto_drivers_num <= crypto_drivers_num) {
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
printf("crypto: driver count wraparound!\n");
return -1;
}
@ -450,7 +454,7 @@ crypto_get_driverid(u_int32_t flags)
newdrv = malloc(2 * crypto_drivers_num *
sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
if (newdrv == NULL) {
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
printf("crypto: no space to expand driver table!\n");
return -1;
}
@ -471,7 +475,7 @@ crypto_get_driverid(u_int32_t flags)
if (bootverbose)
printf("crypto: assign driver %u, flags %u\n", i, flags);
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return i;
}
@ -496,7 +500,7 @@ crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags,
struct cryptocap *cap;
int err;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
cap = crypto_checkdriver(driverid);
if (cap != NULL &&
@ -525,7 +529,7 @@ crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags,
} else
err = EINVAL;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return err;
}
@ -544,7 +548,7 @@ crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
struct cryptocap *cap;
int err;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
cap = crypto_checkdriver(driverid);
/* NB: algorithms are in the range [1..max] */
@ -579,7 +583,7 @@ crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
} else
err = EINVAL;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return err;
}
@ -596,7 +600,7 @@ crypto_unregister(u_int32_t driverid, int alg)
u_int32_t ses;
struct cryptocap *cap;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
cap = crypto_checkdriver(driverid);
if (cap != NULL &&
@ -625,7 +629,7 @@ crypto_unregister(u_int32_t driverid, int alg)
} else
err = EINVAL;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return err;
}
@ -647,7 +651,7 @@ crypto_unregister_all(u_int32_t driverid)
u_int32_t ses;
struct cryptocap *cap;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
cap = crypto_checkdriver(driverid);
if (cap != NULL) {
for (i = CRYPTO_ALGORITHM_MIN; i <= CRYPTO_ALGORITHM_MAX; i++) {
@ -667,7 +671,7 @@ crypto_unregister_all(u_int32_t driverid)
} else
err = EINVAL;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return err;
}
@ -681,7 +685,7 @@ crypto_unblock(u_int32_t driverid, int what)
struct cryptocap *cap;
int needwakeup, err;
mutex_spin_enter(&crypto_mtx);
mutex_spin_enter(&crypto_q_mtx);
cap = crypto_checkdriver(driverid);
if (cap != NULL) {
needwakeup = 0;
@ -694,12 +698,12 @@ crypto_unblock(u_int32_t driverid, int what)
cap->cc_kqblocked = 0;
}
err = 0;
mutex_spin_exit(&crypto_mtx);
if (needwakeup)
setsoftcrypto(softintr_cookie);
mutex_spin_exit(&crypto_q_mtx);
} else {
err = EINVAL;
mutex_spin_exit(&crypto_mtx);
mutex_spin_exit(&crypto_q_mtx);
}
return err;
@ -715,7 +719,7 @@ crypto_dispatch(struct cryptop *crp)
u_int32_t hid = CRYPTO_SESID2HID(crp->crp_sid);
int result;
mutex_spin_enter(&crypto_mtx);
mutex_spin_enter(&crypto_q_mtx);
DPRINTF(("crypto_dispatch: crp %p, reqid 0x%x, alg %d\n",
crp, crp->crp_reqid, crp->crp_desc->crd_alg));
@ -734,7 +738,7 @@ crypto_dispatch(struct cryptop *crp)
*/
cap = crypto_checkdriver(hid);
if (cap && !cap->cc_qblocked) {
mutex_spin_exit(&crypto_mtx);
mutex_spin_exit(&crypto_q_mtx);
result = crypto_invoke(crp, 0);
if (result == ERESTART) {
/*
@ -742,11 +746,11 @@ crypto_dispatch(struct cryptop *crp)
* driver ``blocked'' for cryptop's and put
* the op on the queue.
*/
mutex_spin_enter(&crypto_mtx);
mutex_spin_enter(&crypto_q_mtx);
crypto_drivers[hid].cc_qblocked = 1;
TAILQ_INSERT_HEAD(&crp_q, crp, crp_next);
cryptostats.cs_blocks++;
mutex_spin_exit(&crypto_mtx);
mutex_spin_exit(&crypto_q_mtx);
}
goto out_released;
} else {
@ -767,8 +771,8 @@ crypto_dispatch(struct cryptop *crp)
*/
TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
if (wasempty) {
mutex_spin_exit(&crypto_mtx);
setsoftcrypto(softintr_cookie);
mutex_spin_exit(&crypto_q_mtx);
result = 0;
goto out_released;
}
@ -776,7 +780,7 @@ crypto_dispatch(struct cryptop *crp)
result = 0;
}
mutex_spin_exit(&crypto_mtx);
mutex_spin_exit(&crypto_q_mtx);
out_released:
return result;
}
@ -791,12 +795,12 @@ crypto_kdispatch(struct cryptkop *krp)
struct cryptocap *cap;
int result;
mutex_spin_enter(&crypto_mtx);
mutex_spin_enter(&crypto_q_mtx);
cryptostats.cs_kops++;
cap = crypto_checkdriver(krp->krp_hid);
if (cap && !cap->cc_kqblocked) {
mutex_spin_exit(&crypto_mtx);
mutex_spin_exit(&crypto_q_mtx);
result = crypto_kinvoke(krp, 0);
if (result == ERESTART) {
/*
@ -804,11 +808,11 @@ crypto_kdispatch(struct cryptkop *krp)
* driver ``blocked'' for cryptop's and put
* the op on the queue.
*/
mutex_spin_enter(&crypto_mtx);
mutex_spin_enter(&crypto_q_mtx);
crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
TAILQ_INSERT_HEAD(&crp_kq, krp, krp_next);
cryptostats.cs_kblocks++;
mutex_spin_exit(&crypto_mtx);
mutex_spin_exit(&crypto_q_mtx);
}
} else {
/*
@ -817,7 +821,7 @@ crypto_kdispatch(struct cryptkop *krp)
*/
TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
result = 0;
mutex_spin_exit(&crypto_mtx);
mutex_spin_exit(&crypto_q_mtx);
}
return result;
@ -841,7 +845,7 @@ crypto_kinvoke(struct cryptkop *krp, int hint)
return EINVAL;
}
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
for (hid = 0; hid < crypto_drivers_num; hid++) {
if ((crypto_drivers[hid].cc_flags & CRYPTOCAP_F_SOFTWARE) &&
crypto_devallowsoft == 0)
@ -859,11 +863,11 @@ crypto_kinvoke(struct cryptkop *krp, int hint)
process = crypto_drivers[hid].cc_kprocess;
arg = crypto_drivers[hid].cc_karg;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
krp->krp_hid = hid;
error = (*process)(arg, krp, hint);
} else {
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
error = ENODEV;
}
@ -924,16 +928,19 @@ crypto_invoke(struct cryptop *crp, int hint)
hid = CRYPTO_SESID2HID(crp->crp_sid);
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
if (hid < crypto_drivers_num) {
int (*process)(void *, struct cryptop *, int);
void *arg;
if (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP)
if (crypto_drivers[hid].cc_flags & CRYPTOCAP_F_CLEANUP) {
mutex_exit(&crypto_mtx);
crypto_freesession(crp->crp_sid);
mutex_enter(&crypto_mtx);
}
process = crypto_drivers[hid].cc_process;
arg = crypto_drivers[hid].cc_arg;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
/*
* Invoke the driver to process the request.
@ -951,11 +958,12 @@ crypto_invoke(struct cryptop *crp, int hint)
for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
mutex_exit(&crypto_mtx);
if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI), 0) == 0)
crp->crp_sid = nid;
crp->crp_etype = EAGAIN;
mutex_spin_exit(&crypto_mtx);
crypto_done(crp);
return 0;
@ -1050,9 +1058,9 @@ crypto_done(struct cryptop *crp)
* callback routine does very little (e.g. the
* /dev/crypto callback method just does a wakeup).
*/
mutex_spin_enter(&crypto_mtx);
mutex_spin_enter(&crypto_ret_q_mtx);
crp->crp_flags |= CRYPTO_F_DONE;
mutex_spin_exit(&crypto_mtx);
mutex_spin_exit(&crypto_ret_q_mtx);
#ifdef CRYPTO_TIMING
if (crypto_timing) {
@ -1069,7 +1077,7 @@ crypto_done(struct cryptop *crp)
#endif
crp->crp_callback(crp);
} else {
mutex_spin_enter(&crypto_mtx);
mutex_spin_enter(&crypto_ret_q_mtx);
crp->crp_flags |= CRYPTO_F_DONE;
if (crp->crp_flags & CRYPTO_F_USER) {
@ -1096,7 +1104,7 @@ crypto_done(struct cryptop *crp)
cv_signal(&cryptoret_cv);
}
}
mutex_spin_exit(&crypto_mtx);
mutex_spin_exit(&crypto_ret_q_mtx);
}
}
@ -1122,13 +1130,13 @@ crypto_kdone(struct cryptkop *krp)
if (krp->krp_flags & CRYPTO_F_CBIMM) {
krp->krp_callback(krp);
} else {
mutex_spin_enter(&crypto_mtx);
mutex_spin_enter(&crypto_ret_q_mtx);
wasempty = TAILQ_EMPTY(&crp_ret_kq);
krp->krp_flags |= CRYPTO_F_ONRETQ;
TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
if (wasempty)
cv_signal(&cryptoret_cv);
mutex_spin_exit(&crypto_mtx);
mutex_spin_exit(&crypto_ret_q_mtx);
}
}
@ -1137,7 +1145,7 @@ crypto_getfeat(int *featp)
{
int hid, kalg, feat = 0;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
if (crypto_userasymcrypto == 0)
goto out;
@ -1155,7 +1163,7 @@ crypto_getfeat(int *featp)
feat |= 1 << kalg;
}
out:
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
*featp = feat;
return (0);
}
@ -1172,7 +1180,7 @@ cryptointr(void)
int result, hint;
cryptostats.cs_intrs++;
mutex_spin_enter(&crypto_mtx);
mutex_spin_enter(&crypto_q_mtx);
do {
/*
* Find the first element in the queue that can be
@ -1214,11 +1222,11 @@ cryptointr(void)
}
if (submit != NULL) {
TAILQ_REMOVE(&crp_q, submit, crp_next);
mutex_spin_exit(&crypto_mtx);
mutex_spin_exit(&crypto_q_mtx);
result = crypto_invoke(submit, hint);
/* we must take here as the TAILQ op or kinvoke
may need this mutex below. sigh. */
mutex_spin_enter(&crypto_mtx);
mutex_spin_enter(&crypto_q_mtx);
if (result == ERESTART) {
/*
* The driver ran out of resources, mark the
@ -1248,10 +1256,10 @@ cryptointr(void)
}
if (krp != NULL) {
TAILQ_REMOVE(&crp_kq, krp, krp_next);
mutex_spin_exit(&crypto_mtx);
mutex_spin_exit(&crypto_q_mtx);
result = crypto_kinvoke(krp, 0);
/* the next iteration will want the mutex. :-/ */
mutex_spin_enter(&crypto_mtx);
mutex_spin_enter(&crypto_q_mtx);
if (result == ERESTART) {
/*
* The driver ran out of resources, mark the
@ -1269,7 +1277,7 @@ cryptointr(void)
}
}
} while (submit != NULL || krp != NULL);
mutex_spin_exit(&crypto_mtx);
mutex_spin_exit(&crypto_q_mtx);
}
/*
@ -1281,7 +1289,7 @@ cryptoret(void)
struct cryptop *crp;
struct cryptkop *krp;
mutex_spin_enter(&crypto_mtx);
mutex_spin_enter(&crypto_ret_q_mtx);
for (;;) {
crp = TAILQ_FIRST(&crp_ret_q);
if (crp != NULL) {
@ -1297,11 +1305,11 @@ cryptoret(void)
/* drop before calling any callbacks. */
if (crp == NULL && krp == NULL) {
cryptostats.cs_rets++;
cv_wait(&cryptoret_cv, &crypto_mtx);
cv_wait(&cryptoret_cv, &crypto_ret_q_mtx);
continue;
}
mutex_spin_exit(&crypto_mtx);
mutex_spin_exit(&crypto_ret_q_mtx);
if (crp != NULL) {
#ifdef CRYPTO_TIMING
@ -1324,6 +1332,6 @@ cryptoret(void)
if (krp != NULL)
krp->krp_callback(krp);
mutex_spin_enter(&crypto_mtx);
mutex_spin_enter(&crypto_ret_q_mtx);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: cryptodev.c,v 1.56 2011/05/06 21:48:46 drochner Exp $ */
/* $NetBSD: cryptodev.c,v 1.57 2011/05/16 10:27:49 drochner Exp $ */
/* $FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.4.2.4 2003/06/03 00:09:02 sam Exp $ */
/* $OpenBSD: cryptodev.c,v 1.53 2002/07/10 22:21:30 mickey Exp $ */
@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.56 2011/05/06 21:48:46 drochner Exp $");
__KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.57 2011/05/16 10:27:49 drochner Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -237,16 +237,16 @@ cryptof_ioctl(struct file *fp, u_long cmd, void *data)
struct fcrypt *criofcr;
int criofd;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
getnanotime(&fcr->atime);
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
switch (cmd) {
case CRIOGET: /* XXX deprecated, remove after 5.0 */
if ((error = fd_allocfile(&criofp, &criofd)) != 0)
return error;
criofcr = pool_get(&fcrpl, PR_WAITOK);
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
TAILQ_INIT(&criofcr->csessions);
TAILQ_INIT(&criofcr->crp_ret_mq);
TAILQ_INIT(&criofcr->crp_ret_mkq);
@ -258,7 +258,7 @@ cryptof_ioctl(struct file *fp, u_long cmd, void *data)
*/
criofcr->sesn = 1;
criofcr->requestid = 1;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
(void)fd_clone(criofp, criofd, (FREAD|FWRITE),
&cryptofops, criofcr);
*(u_int32_t *)data = criofd;
@ -278,9 +278,9 @@ cryptof_ioctl(struct file *fp, u_long cmd, void *data)
goto mbail;
}
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
fcr->mtime = fcr->atime;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
error = cryptodev_msession(fcr, snop, sgop->count);
if (error) {
goto mbail;
@ -292,22 +292,22 @@ mbail:
kmem_free(snop, sgop->count * sizeof(struct session_n_op));
break;
case CIOCFSESSION:
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
fcr->mtime = fcr->atime;
ses = *(u_int32_t *)data;
cse = csefind(fcr, ses);
if (cse == NULL) {
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return EINVAL;
}
csedelete(fcr, cse);
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
error = csefree(cse);
break;
case CIOCNFSESSION:
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
fcr->mtime = fcr->atime;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
sfop = (struct crypt_sfop *)data;
sesid = kmem_alloc((sfop->count * sizeof(u_int32_t)),
KM_SLEEP);
@ -319,11 +319,11 @@ mbail:
kmem_free(sesid, (sfop->count * sizeof(u_int32_t)));
break;
case CIOCCRYPT:
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
fcr->mtime = fcr->atime;
cop = (struct crypt_op *)data;
cse = csefind(fcr, cop->ses);
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
if (cse == NULL) {
DPRINTF(("csefind failed\n"));
return EINVAL;
@ -332,9 +332,9 @@ mbail:
DPRINTF(("cryptodev_op error = %d\n", error));
break;
case CIOCNCRYPTM:
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
fcr->mtime = fcr->atime;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
mop = (struct crypt_mop *)data;
cnop = kmem_alloc((mop->count * sizeof(struct crypt_n_op)),
KM_SLEEP);
@ -354,9 +354,9 @@ mbail:
DPRINTF(("cryptodev_key error = %d\n", error));
break;
case CIOCNFKEYM:
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
fcr->mtime = fcr->atime;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
mkop = (struct crypt_mkop *)data;
knop = kmem_alloc((mkop->count * sizeof(struct crypt_n_kop)),
KM_SLEEP);
@ -374,9 +374,9 @@ mbail:
error = crypto_getfeat((int *)data);
break;
case CIOCNCRYPTRETM:
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
fcr->mtime = fcr->atime;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
crypt_ret = (struct cryptret *)data;
count = crypt_ret->count;
crypt_res = kmem_alloc((count * sizeof(struct crypt_result)),
@ -619,7 +619,7 @@ cryptodev_op(struct csession *cse, struct crypt_op *cop, struct lwp *l)
eagain:
#endif
error = crypto_dispatch(crp);
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
/*
* If the request was going to be completed by the
@ -632,7 +632,7 @@ eagain:
switch (error) {
#ifdef notyet /* don't loop forever -- but EAGAIN not possible here yet */
case EAGAIN:
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
goto eagain;
break;
#endif
@ -640,7 +640,7 @@ eagain:
break;
default:
DPRINTF(("cryptodev_op: not waiting, error.\n"));
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
goto bail;
}
@ -656,7 +656,7 @@ eagain:
DPRINTF(("cryptodev_op: DONE, not woken by cryptoret.\n"));
(void)crypto_ret_q_remove(crp);
}
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
if (crp->crp_etype != 0) {
DPRINTF(("cryptodev_op: crp_etype %d\n", crp->crp_etype));
@ -712,18 +712,18 @@ cryptodev_cb(void *op)
struct csession *cse = (struct csession *)crp->crp_opaque;
int error = 0;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
cse->error = crp->crp_etype;
if (crp->crp_etype == EAGAIN) {
/* always drop mutex to call dispatch routine */
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
error = crypto_dispatch(crp);
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
}
if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
cv_signal(&crp->crp_cv);
}
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return 0;
}
@ -734,12 +734,12 @@ cryptodev_mcb(void *op)
struct csession *cse = (struct csession *)crp->crp_opaque;
int error=0;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
cse->error = crp->crp_etype;
if (crp->crp_etype == EAGAIN) {
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
error = crypto_dispatch(crp);
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
}
if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
cv_signal(&crp->crp_cv);
@ -747,7 +747,7 @@ cryptodev_mcb(void *op)
TAILQ_INSERT_TAIL(&crp->fcrp->crp_ret_mq, crp, crp_next);
selnotify(&crp->fcrp->sinfo, 0, 0);
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return 0;
}
@ -756,9 +756,9 @@ cryptodevkey_cb(void *op)
{
struct cryptkop *krp = op;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
cv_signal(&krp->krp_cv);
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return 0;
}
@ -767,11 +767,11 @@ cryptodevkey_mcb(void *op)
{
struct cryptkop *krp = op;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
cv_signal(&krp->krp_cv);
TAILQ_INSERT_TAIL(&krp->fcrp->crp_ret_mkq, krp, krp_next);
selnotify(&krp->fcrp->sinfo, 0, 0);
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return 0;
}
@ -866,7 +866,7 @@ cryptodev_key(struct crypt_kop *kop)
goto fail;
}
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
while (!(krp->krp_flags & CRYPTO_F_DONE)) {
cv_wait(&krp->krp_cv, &crypto_mtx); /* XXX cv_wait_sig? */
}
@ -874,7 +874,7 @@ cryptodev_key(struct crypt_kop *kop)
DPRINTF(("cryptodev_key: DONE early, not via cryptoret.\n"));
(void)crypto_ret_kq_remove(krp);
}
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
if (krp->krp_status != 0) {
DPRINTF(("cryptodev_key: krp->krp_status 0x%08x\n",
@ -921,16 +921,16 @@ cryptof_close(struct file *fp)
struct fcrypt *fcr = fp->f_data;
struct csession *cse;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
while ((cse = TAILQ_FIRST(&fcr->csessions))) {
TAILQ_REMOVE(&fcr->csessions, cse, next);
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
(void)csefree(cse);
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
}
seldestroy(&fcr->sinfo);
fp->f_data = NULL;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
pool_put(&fcrpl, fcr);
return 0;
@ -976,12 +976,12 @@ csedelete(struct fcrypt *fcr, struct csession *cse_del)
static struct csession *
cseadd(struct fcrypt *fcr, struct csession *cse)
{
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
/* don't let session ID wrap! */
if (fcr->sesn + 1 == 0) return NULL;
TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
cse->ses = fcr->sesn++;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return cse;
}
@ -1048,7 +1048,7 @@ cryptoopen(dev_t dev, int flag, int mode,
fcr = pool_get(&fcrpl, PR_WAITOK);
getnanotime(&fcr->btime);
fcr->atime = fcr->mtime = fcr->btime;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
TAILQ_INIT(&fcr->csessions);
TAILQ_INIT(&fcr->crp_ret_mq);
TAILQ_INIT(&fcr->crp_ret_mkq);
@ -1059,7 +1059,7 @@ cryptoopen(dev_t dev, int flag, int mode,
*/
fcr->sesn = 1;
fcr->requestid = 1;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return fd_clone(fp, fd, flag, &cryptofops, fcr);
}
@ -1109,15 +1109,15 @@ cryptodev_mop(struct fcrypt *fcr,
int iov_len;
for (req = 0; req < count; req++) {
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
cse = csefind(fcr, cnop[req].ses);
if (cse == NULL) {
DPRINTF(("csefind failed\n"));
cnop[req].status = EINVAL;
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
continue;
}
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
if (cnop[req].len > 256*1024-4) {
DPRINTF(("length failed\n"));
@ -1304,12 +1304,12 @@ cryptodev_mop(struct fcrypt *fcr,
eagain:
#endif
cnop[req].status = crypto_dispatch(crp);
mutex_spin_enter(&crypto_mtx); /* XXX why mutex? */
mutex_enter(&crypto_mtx); /* XXX why mutex? */
switch (cnop[req].status) {
#ifdef notyet /* don't loop forever -- but EAGAIN not possible here yet */
case EAGAIN:
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
goto eagain;
break;
#endif
@ -1317,11 +1317,11 @@ eagain:
break;
default:
DPRINTF(("cryptodev_op: not waiting, error.\n"));
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
goto bail;
}
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
bail:
if (cnop[req].status) {
if (crp) {
@ -1708,17 +1708,17 @@ cryptodev_msessionfin(struct fcrypt *fcr, int count, u_int32_t *sesid)
struct csession *cse;
int req, error = 0;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
for(req = 0; req < count; req++) {
cse = csefind(fcr, sesid[req]);
if (cse == NULL)
continue;
csedelete(fcr, cse);
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
error = csefree(cse);
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
}
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return 0;
}
@ -1750,7 +1750,7 @@ cryptodev_getmstatus(struct fcrypt *fcr, struct crypt_result *crypt_res,
* if 3 then 2 symmetric and 1 asymmetric and so on */
/* pull off a list of requests while protected from changes */
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
while (req < count) {
crp = TAILQ_FIRST(&fcr->crp_ret_mq);
if (crp) {
@ -1778,7 +1778,7 @@ cryptodev_getmstatus(struct fcrypt *fcr, struct crypt_result *crypt_res,
}
}
}
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
/* now do all the work outside the mutex */
for(req=0; req < count ;) {
@ -1884,7 +1884,7 @@ cryptodev_getstatus (struct fcrypt *fcr, struct crypt_result *crypt_res)
struct csession *cse;
int i, size, req = 0;
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
/* Here we dont know for which request the user is requesting the
* response so checking in both the queues */
TAILQ_FOREACH_SAFE(crp, &fcr->crp_ret_mq, crp_next, cnext) {
@ -1920,7 +1920,7 @@ cryptodev_getstatus (struct fcrypt *fcr, struct crypt_result *crypt_res)
bail:
TAILQ_REMOVE(&fcr->crp_ret_mq, crp, crp_next);
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
crypto_freereq(crp);
return 0;
}
@ -1955,7 +1955,7 @@ bail:
}
fail:
TAILQ_REMOVE(&fcr->crp_ret_mkq, krp, krp_next);
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
/* not sure what to do for this */
/* kop[req].crk_status = krp->krp_status; */
for (i = 0; i < CRK_MAXPARAM; i++) {
@ -1972,7 +1972,7 @@ fail:
return 0;
}
}
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return EINPROGRESS;
}
@ -1983,14 +1983,14 @@ cryptof_stat(struct file *fp, struct stat *st)
(void)memset(st, 0, sizeof(st));
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
st->st_dev = makedev(cdevsw_lookup_major(&crypto_cdevsw), fcr->sesn);
st->st_atimespec = fcr->atime;
st->st_mtimespec = fcr->mtime;
st->st_ctimespec = st->st_birthtimespec = fcr->btime;
st->st_uid = kauth_cred_geteuid(fp->f_cred);
st->st_gid = kauth_cred_getegid(fp->f_cred);
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return 0;
}
@ -2006,7 +2006,7 @@ cryptof_poll(struct file *fp, int events)
return 0;
}
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
if (TAILQ_EMPTY(&fcr->crp_ret_mq) && TAILQ_EMPTY(&fcr->crp_ret_mkq)) {
/* no completed requests pending, save the poll for later */
selrecord(curlwp, &fcr->sinfo);
@ -2014,7 +2014,7 @@ cryptof_poll(struct file *fp, int events)
/* let the app(s) know that there are completed requests */
revents = events & (POLLIN | POLLRDNORM);
}
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
return revents;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ocryptodev.c,v 1.3 2011/02/19 16:26:34 drochner Exp $ */
/* $NetBSD: ocryptodev.c,v 1.4 2011/05/16 10:27:49 drochner Exp $ */
/* $FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.4.2.4 2003/06/03 00:09:02 sam Exp $ */
/* $OpenBSD: cryptodev.c,v 1.53 2002/07/10 22:21:30 mickey Exp $ */
@ -69,7 +69,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ocryptodev.c,v 1.3 2011/02/19 16:26:34 drochner Exp $");
__KERNEL_RCSID(0, "$NetBSD: ocryptodev.c,v 1.4 2011/05/16 10:27:49 drochner Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -143,10 +143,10 @@ mbail:
kmem_free(osnop, osgop->count * sizeof(struct osession_n_op));
break;
case OCIOCCRYPT:
mutex_spin_enter(&crypto_mtx);
mutex_enter(&crypto_mtx);
ocop = (struct ocrypt_op *)data;
cse = cryptodev_csefind(fcr, ocop->ses);
mutex_spin_exit(&crypto_mtx);
mutex_exit(&crypto_mtx);
if (cse == NULL) {
DPRINTF(("csefind failed\n"));
return EINVAL;