From 161ff0f03667052d20a1d997f9e8a945563136fd Mon Sep 17 00:00:00 2001 From: pjd Date: Mon, 22 May 2006 07:48:45 +0000 Subject: 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. --- sys/opencrypto/crypto.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) (limited to 'sys/opencrypto/crypto.c') 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 -- cgit v1.1