summaryrefslogtreecommitdiffstats
path: root/sys/opencrypto/crypto.c
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2006-05-22 07:48:45 +0000
committerpjd <pjd@FreeBSD.org>2006-05-22 07:48:45 +0000
commit161ff0f03667052d20a1d997f9e8a945563136fd (patch)
tree21816577fcd10f3c20d67262fa7c3e16c6f9a566 /sys/opencrypto/crypto.c
parent04beefe3f75547ae3500d4e4a187810d08831fe6 (diff)
downloadFreeBSD-src-161ff0f03667052d20a1d997f9e8a945563136fd.zip
FreeBSD-src-161ff0f03667052d20a1d997f9e8a945563136fd.tar.gz
We must synchronize access to cc_qblocked, because there could be a race
where crypto_invoke() returns ERESTART and before we set cc_qblocked to 1, crypto_unblock() is called and sets it to 0. This way we mark device as blocked forever. Fix it by not setting cc_qblocked in the fast path and by protecting crypto_invoke() in the crypto_proc thread with CRYPTO_Q_LOCK(). This won't slow things down, because there is no contention - we have only one crypto thread. Actually it can be slightly faster, because we save two atomic ops per crypto request. The fast code path remains lock-less.
Diffstat (limited to 'sys/opencrypto/crypto.c')
-rw-r--r--sys/opencrypto/crypto.c21
1 files changed, 4 insertions, 17 deletions
diff --git a/sys/opencrypto/crypto.c b/sys/opencrypto/crypto.c
index 74f147e..38d285c 100644
--- a/sys/opencrypto/crypto.c
+++ b/sys/opencrypto/crypto.c
@@ -694,19 +694,10 @@ crypto_dispatch(struct cryptop *crp)
result = crypto_invoke(cap, crp, 0);
if (result != ERESTART)
return (result);
- else {
- /*
- * The driver ran out of resources, mark the
- * driver ``blocked'' for cryptop's and put
- * the request on the queue.
- *
- * XXX ops are placed at the tail so their
- * order is preserved but this can place them
- * behind batch'd ops.
- */
- cap->cc_qblocked = 1;
- cryptostats.cs_blocks++;
- }
+ /*
+ * The driver ran out of resources, put the request on
+ * the queue.
+ */
}
}
CRYPTO_Q_LOCK();
@@ -1102,13 +1093,11 @@ crypto_proc(void)
}
if (submit != NULL) {
TAILQ_REMOVE(&crp_q, submit, crp_next);
- CRYPTO_Q_UNLOCK();
hid = CRYPTO_SESID2HID(submit->crp_sid);
cap = crypto_checkdriver(hid);
KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
__func__, __LINE__));
result = crypto_invoke(cap, submit, hint);
- CRYPTO_Q_LOCK();
if (result == ERESTART) {
/*
* The driver ran out of resources, mark the
@@ -1138,9 +1127,7 @@ crypto_proc(void)
}
if (krp != NULL) {
TAILQ_REMOVE(&crp_kq, krp, krp_next);
- CRYPTO_Q_UNLOCK();
result = crypto_kinvoke(krp);
- CRYPTO_Q_LOCK();
if (result == ERESTART) {
/*
* The driver ran out of resources, mark the
OpenPOWER on IntegriCloud