mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
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.
This commit is contained in:
parent
c4d39d8076
commit
bda0abc627
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=158823
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user