summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2016-05-31 15:11:27 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2016-05-31 15:11:27 +0000
commit3c0b674170991b74c9325878e529746e7a18cf66 (patch)
treea4b8230891037e2cc09006bb81a158d2c2906639 /sys
parent168ff708eec99ea323f0a5eeac5125ce595ccb23 (diff)
Ensure that softraid crypto is not run on the crypto taskq.
When softraid crypto was written, it was intended that all crypto operations would be run by softraid. As such, it called crypto_invoke() directly, rather than crypto_dispatch() which would queue the task for later processing. However, r1.53 of crypto/crypto.c started running completion callbacks as a separate task. This leads to deadlocks with the crypto taskq blocking in biowait, when softraid crypto volumes are stacked (often with vnds). In order to avoid task queueing and ensure that the operations are run within softraid, set the CRYPTO_F_NOQUEUE flag. With r1.62 of crypto/crypto.c crypto_dispatch() also started respecting this flag, hence we can also switch back to calling the standard crypto_dispatch() interface, rather than calling crypto_invoke() directly. Tested by Peter Wens (peter at wenka dot nl) - thanks! ok krw@ mlarkin@ mikeb@ tedu@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/softraid_crypto.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/sys/dev/softraid_crypto.c b/sys/dev/softraid_crypto.c
index 3c0648b9550..736645c5dc6 100644
--- a/sys/dev/softraid_crypto.c
+++ b/sys/dev/softraid_crypto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid_crypto.c,v 1.129 2016/05/28 00:10:36 tedu Exp $ */
+/* $OpenBSD: softraid_crypto.c,v 1.130 2016/05/31 15:11:26 jsing Exp $ */
/*
* Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2008 Hans-Joerg Hoexer <hshoexer@openbsd.org>
@@ -295,7 +295,7 @@ sr_crypto_prepare(struct sr_workunit *wu, int encrypt)
crwu->cr_crp->crp_opaque = crwu;
crwu->cr_crp->crp_ilen = xs->datalen;
crwu->cr_crp->crp_alloctype = M_DEVBUF;
- crwu->cr_crp->crp_flags = CRYPTO_F_IOV;
+ crwu->cr_crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_NOQUEUE;
crwu->cr_crp->crp_buf = &crwu->cr_uio;
for (i = 0, crd = crwu->cr_crp->crp_desc; crd;
i++, blkno++, crd = crd->crd_next) {
@@ -1097,7 +1097,7 @@ sr_crypto_rw(struct sr_workunit *wu)
if (wu->swu_xs->flags & SCSI_DATA_OUT) {
crwu = sr_crypto_prepare(wu, 1);
crwu->cr_crp->crp_callback = sr_crypto_write;
- rv = crypto_invoke(crwu->cr_crp);
+ rv = crypto_dispatch(crwu->cr_crp);
if (rv == 0)
rv = crwu->cr_crp->crp_etype;
} else
@@ -1173,9 +1173,9 @@ sr_crypto_done(struct sr_workunit *wu)
if (ISSET(xs->flags, SCSI_DATA_IN) && xs->error == XS_NOERROR) {
crwu = sr_crypto_prepare(wu, 0);
crwu->cr_crp->crp_callback = sr_crypto_read;
- DNPRINTF(SR_D_INTR, "%s: sr_crypto_done: crypto_invoke %p\n",
+ DNPRINTF(SR_D_INTR, "%s: sr_crypto_done: crypto_dispatch %p\n",
DEVNAME(wu->swu_dis->sd_sc), crwu->cr_crp);
- crypto_invoke(crwu->cr_crp);
+ crypto_dispatch(crwu->cr_crp);
return;
}