From: Zhushuai Yin <yinzhushuai@huawei.com> When the SEC processing cores are disabled during an async cipher or digest operation, wd_do_cipher_async/send still succeeds because the doorbell is an MMIO write to the QM (Queue Manager), which is an independent hardware module from the processing cores. However, the poll thread fails to receive a CQE (cores disabled, no one writes CQE, phase never flips) and retries ASYNC_MAX_RETRY_CNT times before giving up. The callback is never invoked because wd_cipher_poll_ctx/ wd_digest_poll_ctx returns an error before calling the callback, so priv->req.state remains 0. async_pause_job returns a positive value (the async fd exists), and the existing check (!ret || priv->req.state) evaluates to false, so the soft fallback is skipped. For cipher, the output buffer stays unfilled and the encrypt-decrypt round-trip fails with ret=252. For digest, the output buffer stays unfilled and the final hash value is incorrect (silent error in first-block mode, already-fail in stream mode). Pre-priv->req.state with STATE_FAIL before sending the async request, matching the existing pattern in AEAD, RSA, DH, and ECC. When the callback is invoked successfully, it overwrites req.state with the actual HW result (0 on success). When the callback is never invoked (poll thread gives up), req.state remains STATE_FAIL (non-zero), so the existing !ret || priv->req.state check correctly triggers soft fallback. Signed-off-by: Zhushuai Yin <yinzhushuai@huawei.com> --- src/uadk_cipher.c | 3 +++ src/uadk_digest.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/uadk_cipher.c b/src/uadk_cipher.c index 8e738e1..5c28d62 100644 --- a/src/uadk_cipher.c +++ b/src/uadk_cipher.c @@ -55,6 +55,8 @@ struct sw_cipher_t { const EVP_CIPHER *(*get_cipher)(void); }; +#define STATE_FAIL 0xFFFF + struct cipher_priv_ctx { handle_t sess; struct wd_cipher_sess_setup setup; @@ -603,6 +605,7 @@ static int do_cipher_async(struct cipher_priv_ctx *priv, struct async_op *op) cb_param->priv = priv; priv->req.cb = uadk_e_cipher_cb; priv->req.cb_param = cb_param; + priv->req.state = STATE_FAIL; ret = async_get_free_task(&idx); if (!ret) diff --git a/src/uadk_digest.c b/src/uadk_digest.c index 2721ff1..75cc5d9 100644 --- a/src/uadk_digest.c +++ b/src/uadk_digest.c @@ -49,6 +49,7 @@ #define SHA_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT (512) #define MAX_DIGEST_LENGTH 64 #define DIGEST_BLOCK_SIZE (512 * 1024) +#define STATE_FAIL 0xFFFF /* * copied form openssl/include/internal/sm3.h @@ -856,6 +857,7 @@ static int do_digest_async(struct digest_priv_ctx *priv, struct async_op *op) cb_param->priv = priv; priv->req.cb = uadk_e_digest_cb; priv->req.cb_param = cb_param; + priv->req.state = STATE_FAIL; ret = async_get_free_task(&idx); if (!ret) -- 2.43.0