[PATCH 1/4] crypto: engine - clear busy and recheck running in the retry pump loop

From: Chenghai Huang

Date: Mon Nov 09 2026 - 02:44:22 EST


The retry pump loop jumps back to the dequeue path directly, skipping
the idle check that clears engine->busy and rechecks engine->running.

When the loop drains the queue it exits with busy still set, and
crypto_transfer_request() queues a pump only when the engine is not
busy: if the loop ends with the inline error completion in req_err_1,
which queues no pump, the next request is enqueued with nothing to run
it and the engine queue stalls. crypto_engine_stop() also spins
waiting for the stale busy flag, up to failing with -EBUSY, and the
loop keeps submitting to hardware after stop was requested because it
never rechecks running.

Jump to the idle check instead: the loop now clears busy and exits
when the queue is empty, and stops submitting once the engine is no
longer running. Engines without retry support are unaffected.

Fixes: 6a89f492f8e5 ("crypto: engine - support for parallel requests based on retry mechanism")
Signed-off-by: Chenghai Huang <huangchenghai2@xxxxxxxxxx>
---
crypto/crypto_engine.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/crypto/crypto_engine.c b/crypto/crypto_engine.c
index 3d07dd5de4fa..5b669038acb4 100644
--- a/crypto/crypto_engine.c
+++ b/crypto/crypto_engine.c
@@ -82,6 +82,7 @@ static void crypto_pump_requests(struct crypto_engine *engine,
if (!engine->retry_support && engine->cur_req)
goto out;

+check_idle:
/* Check if the engine queue is idle */
if (!crypto_queue_len(&engine->queue) || !engine->running) {
if (!engine->busy)
@@ -98,7 +99,6 @@ static void crypto_pump_requests(struct crypto_engine *engine,
goto out;
}

-start_request:
/* Get the fist request from the engine queue to handle */
backlog = crypto_get_backlog(&engine->queue);
async_req = crypto_dequeue_request(&engine->queue);
@@ -161,7 +161,7 @@ static void crypto_pump_requests(struct crypto_engine *engine,
/* If retry mechanism is supported, send new requests to engine */
if (engine->retry_support) {
spin_lock_irqsave(&engine->queue_lock, flags);
- goto start_request;
+ goto check_idle;
}
return;

--
2.43.0