From nobody Fri Jun 12 11:18:45 2026 Received: from canpmsgout06.his.huawei.com (canpmsgout06.his.huawei.com [113.46.200.221]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8DD8647ECE7; Fri, 15 May 2026 11:47:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.221 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778845655; cv=none; b=S9WDDFlw6ebJXQGhOuzrwkNsankmDwvakRDaVK7+8kFIkuRflE0yfweKAXjfLTsQZVMgT5XfBNW/l54Bzl6cyQaOO62cAeNJ/5pT7w/byaiJ94X6BPhtLTzXPeQjvEnX7a/uPaF6hsqz8/utjeQ1EaZ9smsoGYEq4DiKwT9yIrI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778845655; c=relaxed/simple; bh=Y+B2c66eiSn3w6C5DXydM6iFDVF2x73nuA05dGFDja8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=P1pNQq1vb+4qV2XFqW356rw0nXSWFpfoRgLFi7+8LWhumVv1bEz5tR44kxPVxf9nqd1ot7XyQXDx8W9UvFEzm2ojNKJp57/6CVeoN14wRXEgNX2H1+Cw9aof6XTuxZUThHHw8hUHbDr67dpgRaupYpIpv5O9CF05CnIemK7pyjc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=jT5ROkLg; arc=none smtp.client-ip=113.46.200.221 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="jT5ROkLg" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=4f/mCpezbIUl9t6IsoTMHDrpqSOvVYEMwH362WXuqlQ=; b=jT5ROkLgjt4SRTuDJkl/ySj2NiUtfJ9sBcSD3WvAQXPG9mpR3QsX2lgapb8MLCq2edNkOdH3R 396Rw+mpknnB5tzpkuqXxeCgomuUbkf/wabwDiQ11EownO/9G4MyDoysrX/nWCb2n5S14aP8D9S sKOLuZ9NnoWMG6XHhmofE6o= Received: from mail.maildlp.com (unknown [172.19.162.144]) by canpmsgout06.his.huawei.com (SkyGuard) with ESMTPS id 4gH4xH2ypBzRhQy; Fri, 15 May 2026 19:39:47 +0800 (CST) Received: from kwepemr100008.china.huawei.com (unknown [7.202.195.119]) by mail.maildlp.com (Postfix) with ESMTPS id 70D1440538; Fri, 15 May 2026 19:47:25 +0800 (CST) Received: from localhost.localdomain (10.50.163.32) by kwepemr100008.china.huawei.com (7.202.195.119) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Fri, 15 May 2026 19:47:24 +0800 From: ZongYu Wu To: , CC: , , , , , Subject: [PATCH 2/3] crypto: hisilicon/sec2 - fix UAF in sec_alg_send_backlog Date: Fri, 15 May 2026 19:46:00 +0800 Message-ID: <20260515114601.2492524-3-wuzongyu1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260515114601.2492524-1-wuzongyu1@huawei.com> References: <20260515114601.2492524-1-wuzongyu1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems200001.china.huawei.com (7.221.188.67) To kwepemr100008.china.huawei.com (7.202.195.119) Content-Type: text/plain; charset="utf-8" From: Wenkai Lin After crypto_request_complete() is invoked, the crypto core may immediately free the request structure and its associated tfm context. Consequently, the sec_ctx and qp_ctx are also released. However, sec_alg_send_backlog() can still attempt to access these structures when processing queued requests, resulting in a use-after-free (UAF) bug. Fix this by accessing the backlog list through the long-term qp memory and using the ctx memory only when the backlog list is not empty. Fixes: f0ae287c5045 ("crypto: hisilicon/sec2 - implement full backlog mode = for sec") Signed-off-by: Wenkai Lin Signed-off-by: Zongyu Wu --- drivers/crypto/hisilicon/sec2/sec_crypto.c | 23 +++++++++++----------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hi= silicon/sec2/sec_crypto.c index 2471a4dd0b50..7f2c81170431 100644 --- a/drivers/crypto/hisilicon/sec2/sec_crypto.c +++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c @@ -234,13 +234,15 @@ static int qp_send_message(struct sec_req *req) return -EINPROGRESS; } =20 -static void sec_alg_send_backlog_soft(struct sec_ctx *ctx, struct sec_qp_c= tx *qp_ctx) +static void sec_alg_send_backlog_soft(struct hisi_qp *qp) { struct sec_req *req, *tmp; + struct sec_ctx *ctx; int ret; =20 - list_for_each_entry_safe(req, tmp, &qp_ctx->qp->backlog.list, list) { + list_for_each_entry_safe(req, tmp, &qp->backlog.list, list) { list_del(&req->list); + ctx =3D req->qp_ctx->ctx; ctx->req_op->buf_unmap(ctx, req); if (req->req_id >=3D 0) sec_free_req_id(req); @@ -258,9 +260,8 @@ static void sec_alg_send_backlog_soft(struct sec_ctx *c= tx, struct sec_qp_ctx *qp } } =20 -static void sec_alg_send_backlog(struct sec_ctx *ctx, struct sec_qp_ctx *q= p_ctx) +static void sec_alg_send_backlog(struct hisi_qp *qp) { - struct hisi_qp *qp =3D qp_ctx->qp; struct sec_req *req, *tmp; int ret; =20 @@ -277,7 +278,7 @@ static void sec_alg_send_backlog(struct sec_ctx *ctx, s= truct sec_qp_ctx *qp_ctx) goto unlock; default: /* Release memory resources and send all requests through software. */ - sec_alg_send_backlog_soft(ctx, qp_ctx); + sec_alg_send_backlog_soft(qp); goto unlock; } } @@ -306,6 +307,7 @@ static void sec_req_cb(struct hisi_qp *qp, void *resp) =20 ctx->req_op->buf_unmap(ctx, req); ctx->req_op->callback(ctx, req, err); + sec_alg_send_backlog(qp); } =20 static void sec_req_cb3(struct hisi_qp *qp, void *resp) @@ -331,6 +333,7 @@ static void sec_req_cb3(struct hisi_qp *qp, void *resp) =20 ctx->req_op->buf_unmap(ctx, req); ctx->req_op->callback(ctx, req, err); + sec_alg_send_backlog(qp); } =20 static int sec_alg_send_message_retry(struct sec_req *req) @@ -1673,8 +1676,6 @@ static void sec_update_iv(struct sec_req *req, enum s= ec_alg_type alg_type) static void sec_skcipher_callback(struct sec_ctx *ctx, struct sec_req *req, int err) { - struct sec_qp_ctx *qp_ctx =3D req->qp_ctx; - if (req->req_id >=3D 0) sec_free_req_id(req); =20 @@ -1684,7 +1685,6 @@ static void sec_skcipher_callback(struct sec_ctx *ctx= , struct sec_req *req, sec_update_iv(req, SEC_SKCIPHER); =20 crypto_request_complete(req->base, err); - sec_alg_send_backlog(ctx, qp_ctx); } =20 static void set_aead_auth_iv(struct sec_ctx *ctx, struct sec_req *req) @@ -1923,7 +1923,7 @@ static void sec_aead_callback(struct sec_ctx *c, stru= ct sec_req *req, int err) struct aead_request *a_req =3D req->aead_req.aead_req; struct crypto_aead *tfm =3D crypto_aead_reqtfm(a_req); size_t authsize =3D crypto_aead_authsize(tfm); - struct sec_qp_ctx *qp_ctx =3D req->qp_ctx; + int error =3D err; size_t sz; =20 if (!err && req->c_req.encrypt) { @@ -1934,15 +1934,14 @@ static void sec_aead_callback(struct sec_ctx *c, st= ruct sec_req *req, int err) authsize, a_req->cryptlen + a_req->assoclen); if (unlikely(sz !=3D authsize)) { dev_err(c->dev, "copy out mac err!\n"); - err =3D -EINVAL; + error =3D -EINVAL; } } =20 if (req->req_id >=3D 0) sec_free_req_id(req); =20 - crypto_request_complete(req->base, err); - sec_alg_send_backlog(c, qp_ctx); + crypto_request_complete(req->base, error); } =20 static void sec_request_uninit(struct sec_req *req) --=20 2.43.0 From nobody Fri Jun 12 11:18:45 2026 Received: from canpmsgout09.his.huawei.com (canpmsgout09.his.huawei.com [113.46.200.224]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4B0EC47ECF7; Fri, 15 May 2026 11:47:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.224 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778845659; cv=none; b=u8XS8SPRCKyJC/LwOt3SngM27QYEcwhmiqgAI+a9ySDJPn9GM6ZXAOK6C87KUoJMs8nDNY1pzYrov5wL2VeJY4dtztoZJyXTd8WitB2P6qSQ50pCIqaNTj6QdUolZAKo7FToJVEIFgb2CetZiceajReDvTgFedBL/dlYg4NtCpc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778845659; c=relaxed/simple; bh=I3VQUKnHRI9ymIEh3LXLwWX3fBfVOdGIguEdBVpKGBU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=qQFqBsA/OgDqLR+Va162wxDFulgFNnc4WIt6N2E1sVK683hxYj/uMFYNuq2YjvBL4CDIOUbsZDs98cF4vCTXxH69K23r2L2t8Aemjy+S7YKGxndknVhaVgI1+85bMqi+jKqXQGYcWloVrYXq5wKXDeMbzy+3q33hNnMLR9S9IWg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=uKmFuvVO; arc=none smtp.client-ip=113.46.200.224 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="uKmFuvVO" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=1StHRbjZe33u09qvjJIyBacshDRBsVjhYEI8azP6mPA=; b=uKmFuvVOn/lE3cwsIp8bZ4mlu5Q/rpisBcabCCoduOv3Wy4cDy5SYgZBKHZSk0UTMZJEuTr0y Uttat879KIwOv+0gfyGUVNo7L+dKQ0PvtpoJXCasXV6bdsbellvJ/IUaSo4cipmZOMvxdYrtIDq 98ht5+pSpJ9Fl0V6GsRGNKw= Received: from mail.maildlp.com (unknown [172.19.162.92]) by canpmsgout09.his.huawei.com (SkyGuard) with ESMTPS id 4gH4xJ5dlfz1cyPB; Fri, 15 May 2026 19:39:48 +0800 (CST) Received: from kwepemr100008.china.huawei.com (unknown [7.202.195.119]) by mail.maildlp.com (Postfix) with ESMTPS id DD07440562; Fri, 15 May 2026 19:47:25 +0800 (CST) Received: from localhost.localdomain (10.50.163.32) by kwepemr100008.china.huawei.com (7.202.195.119) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Fri, 15 May 2026 19:47:25 +0800 From: ZongYu Wu To: , CC: , , , , , Subject: [PATCH 3/3] crypto: hisilicon/hpre - implement full backlog support for hpre driver Date: Fri, 15 May 2026 19:46:01 +0800 Message-ID: <20260515114601.2492524-4-wuzongyu1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260515114601.2492524-1-wuzongyu1@huawei.com> References: <20260515114601.2492524-1-wuzongyu1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems200001.china.huawei.com (7.221.188.67) To kwepemr100008.china.huawei.com (7.202.195.119) Content-Type: text/plain; charset="utf-8" From: lizhi When the hardware queue returns -EBUSY, requests are queued instead of being failed immediately. The driver retries queued requests from the completion path after earlier requests have finished. This reduces request failures caused by temporary hardware congestion and improves throughput and stability under high load. Signed-off-by: lizhi Signed-off-by: Zongyu Wu --- drivers/crypto/hisilicon/hpre/hpre_crypto.c | 223 +++++++++++++++----- 1 file changed, 166 insertions(+), 57 deletions(-) diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/h= isilicon/hpre/hpre_crypto.c index 09077abbf6ad..5d5c4d5a9fbc 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c +++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c @@ -30,6 +30,7 @@ struct hpre_ctx; #define HPRE_DH_G_FLAG 0x02 #define HPRE_TRY_SEND_TIMES 100 #define HPRE_INVLD_REQ_ID (-1) +#define HPRE_ALG_TYPE_MASK 0x1F =20 #define HPRE_SQE_ALG_BITS 5 #define HPRE_SQE_DONE_SHIFT 30 @@ -39,6 +40,7 @@ struct hpre_ctx; #define HPRE_DFX_US_TO_NS 1000 =20 #define HPRE_ENABLE_HPCORE_SHIFT 7 +#define HPRE_ECDH_CLR_DATA_SHIFT 2 =20 /* due to nist p521 */ #define HPRE_ECC_MAX_KSZ 66 @@ -138,6 +140,8 @@ struct hpre_asym_request { int err; hpre_cb cb; struct timespec64 req_time; + struct crypto_async_request *base; + struct list_head list; }; =20 static inline unsigned int hpre_align_sz(void) @@ -241,8 +245,8 @@ static void hpre_hw_data_clr_all(struct hpre_ctx *ctx, struct scatterlist *dst, struct scatterlist *src) { - struct device *dev =3D ctx->dev; struct hpre_sqe *sqe =3D &req->req; + struct device *dev =3D ctx->dev; dma_addr_t tmp; =20 tmp =3D le64_to_cpu(sqe->in); @@ -270,6 +274,34 @@ static void hpre_hw_data_clr_all(struct hpre_ctx *ctx, } } =20 +static void hpre_ecdh_hw_data_clr_all(struct hpre_ctx *ctx, + struct hpre_asym_request *req, + struct scatterlist *dst, + struct scatterlist *src) +{ + struct hpre_sqe *sqe =3D &req->req; + struct device *dev =3D ctx->dev; + dma_addr_t dma; + + dma =3D le64_to_cpu(sqe->in); + if (unlikely(dma_mapping_error(dev, dma))) + return; + + /* req->src may contain garbage value, check both src and req->src before= freeing */ + if (src && req->src) + dma_free_coherent(dev, ctx->key_sz << HPRE_ECDH_CLR_DATA_SHIFT, + req->src, dma); + + dma =3D le64_to_cpu(sqe->out); + if (unlikely(dma_mapping_error(dev, dma))) + return; + + if (req->dst) + dma_free_coherent(dev, ctx->key_sz << 1, req->dst, dma); + if (dst) + dma_unmap_single(dev, dma, ctx->key_sz << 1, DMA_FROM_DEVICE); +} + static int hpre_alg_res_post_hf(struct hpre_ctx *ctx, struct hpre_sqe *sqe, void **kreq) { @@ -323,6 +355,94 @@ static bool hpre_is_bd_timeout(struct hpre_asym_reques= t *req, return true; } =20 +static int hpre_send(struct hpre_ctx *ctx, struct hpre_sqe *msg) +{ + struct hpre_dfx *dfx =3D ctx->hpre->debug.dfx; + int cnt =3D 0; + int ret; + + do { + ret =3D hisi_qp_send(ctx->qp, msg); + if (ret !=3D -EBUSY) + break; + atomic64_inc(&dfx[HPRE_SEND_BUSY_CNT].value); + } while (cnt++ < HPRE_TRY_SEND_TIMES); + + if (likely(!ret)) { + atomic64_inc(&dfx[HPRE_SEND_CNT].value); + return ret; + } + + if (ret !=3D -EBUSY) + atomic64_inc(&dfx[HPRE_SEND_FAIL_CNT].value); + + return ret; +} + +static int hpre_send_backlog(struct hpre_ctx *ctx, struct hpre_sqe *msg) +{ + struct hpre_dfx *dfx =3D ctx->hpre->debug.dfx; + int ret; + + ret =3D hisi_qp_send(ctx->qp, msg); + if (likely(!ret)) + atomic64_inc(&dfx[HPRE_SEND_CNT].value); + else if (unlikely(ret !=3D -EBUSY)) + atomic64_inc(&dfx[HPRE_SEND_FAIL_CNT].value); + else + atomic64_inc(&dfx[HPRE_SEND_BUSY_CNT].value); + + return ret; +} + +static void hpre_alg_hw_data_clr_all(struct hpre_ctx *ctx, struct hpre_asy= m_request *h_req) +{ + switch (le32_to_cpu(h_req->req.dw0) & HPRE_ALG_TYPE_MASK) { + case HPRE_ALG_DH_G2: + case HPRE_ALG_DH: + hpre_hw_data_clr_all(ctx, h_req, h_req->areq.dh->dst, h_req->areq.dh->sr= c); + break; + case HPRE_ALG_NC_NCRT: + case HPRE_ALG_NC_CRT: + hpre_hw_data_clr_all(ctx, h_req, h_req->areq.rsa->dst, h_req->areq.rsa->= src); + break; + case HPRE_ALG_ECC_MUL: + hpre_ecdh_hw_data_clr_all(ctx, h_req, h_req->areq.ecdh->dst, h_req->areq= .ecdh->src); + break; + default: + break; + } +} + +static void hpre_alg_send_backlog(struct hisi_qp *qp) +{ + struct hpre_asym_request *req, *tmp; + int ret; + + spin_lock_bh(&qp->backlog.lock); + list_for_each_entry_safe(req, tmp, &qp->backlog.list, list) { + ret =3D hpre_send_backlog(req->ctx, &req->req); + switch (ret) { + case 0: + list_del(&req->list); + crypto_request_complete(req->base, -EINPROGRESS); + break; + case -EBUSY: + /* Device is busy and stop send any request. */ + goto unlock; + default: + /* Current no fallback for any send error. */ + list_del(&req->list); + hpre_alg_hw_data_clr_all(req->ctx, req); + crypto_request_complete(req->base, -EIO); + break; + } + } + +unlock: + spin_unlock_bh(&qp->backlog.lock); +} + static void hpre_dh_cb(struct hpre_ctx *ctx, void *resp) { struct hpre_dfx *dfx =3D ctx->hpre->debug.dfx; @@ -377,6 +497,7 @@ static void hpre_alg_cb(struct hisi_qp *qp, void *resp) } =20 h_req->cb(h_req->ctx, resp); + hpre_alg_send_backlog(qp); } =20 static int hpre_ctx_init(struct hpre_ctx *ctx, u8 type) @@ -450,25 +571,39 @@ static int hpre_msg_request_set(struct hpre_ctx *ctx,= void *req, bool is_rsa) return 0; } =20 -static int hpre_send(struct hpre_ctx *ctx, struct hpre_sqe *msg) +static int hpre_alg_try_enqueue(struct hpre_asym_request *hpre_req) { - struct hpre_dfx *dfx =3D ctx->hpre->debug.dfx; - int ctr =3D 0; + struct hisi_qp *qp =3D hpre_req->ctx->qp; + + /* Check if any request is already backlogged */ + if (!list_empty(&qp->backlog.list)) + return -EBUSY; + + /* Try to enqueue to HW ring */ + return hpre_send_backlog(hpre_req->ctx, &hpre_req->req); +} + +static int hpre_alg_send_message(struct hpre_asym_request *hpre_req) +{ + struct hisi_qp *qp =3D hpre_req->ctx->qp; int ret; =20 - do { - atomic64_inc(&dfx[HPRE_SEND_CNT].value); - ret =3D hisi_qp_send(ctx->qp, msg); - if (ret !=3D -EBUSY) - break; - atomic64_inc(&dfx[HPRE_SEND_BUSY_CNT].value); - } while (ctr++ < HPRE_TRY_SEND_TIMES); + if (!(hpre_req->base->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { + ret =3D hpre_send(hpre_req->ctx, &hpre_req->req); + if (ret =3D=3D -EBUSY) + return -ENOSPC; + } else { + ret =3D hpre_alg_try_enqueue(hpre_req); + if (ret =3D=3D -EBUSY) { + spin_lock_bh(&qp->backlog.lock); + list_add_tail(&hpre_req->list, &qp->backlog.list); + spin_unlock_bh(&qp->backlog.lock); + return -EBUSY; + } + } =20 if (likely(!ret)) - return ret; - - if (ret !=3D -EBUSY) - atomic64_inc(&dfx[HPRE_SEND_FAIL_CNT].value); + return -EINPROGRESS; =20 return ret; } @@ -482,6 +617,7 @@ static int hpre_dh_compute_value(struct kpp_request *re= q) struct hpre_sqe *msg =3D &hpre_req->req; int ret; =20 + hpre_req->base =3D &req->base; ret =3D hpre_msg_request_set(ctx, req, false); if (unlikely(ret)) return ret; @@ -503,14 +639,12 @@ static int hpre_dh_compute_value(struct kpp_request *= req) else msg->dw0 =3D cpu_to_le32(le32_to_cpu(msg->dw0) | HPRE_ALG_DH); =20 - /* success */ - ret =3D hpre_send(ctx, msg); - if (likely(!ret)) - return -EINPROGRESS; + ret =3D hpre_alg_send_message(hpre_req); + if (likely(ret =3D=3D -EINPROGRESS || ret =3D=3D -EBUSY)) + return ret; =20 clear_all: hpre_hw_data_clr_all(ctx, hpre_req, req->dst, req->src); - return ret; } =20 @@ -755,6 +889,7 @@ static int hpre_rsa_enc(struct akcipher_request *req) struct hpre_sqe *msg =3D &hpre_req->req; int ret; =20 + hpre_req->base =3D &req->base; /* For unsupported key size and unavailable devices, use soft tfm instead= */ if (ctx->fallback) { akcipher_request_set_tfm(req, ctx->rsa.soft_tfm); @@ -781,10 +916,9 @@ static int hpre_rsa_enc(struct akcipher_request *req) if (unlikely(ret)) goto clear_all; =20 - /* success */ - ret =3D hpre_send(ctx, msg); - if (likely(!ret)) - return -EINPROGRESS; + ret =3D hpre_alg_send_message(hpre_req); + if (likely(ret =3D=3D -EINPROGRESS || ret =3D=3D -EBUSY)) + return ret; =20 clear_all: hpre_hw_data_clr_all(ctx, hpre_req, req->dst, req->src); @@ -801,6 +935,7 @@ static int hpre_rsa_dec(struct akcipher_request *req) struct hpre_sqe *msg =3D &hpre_req->req; int ret; =20 + hpre_req->base =3D &req->base; /* For unsupported key size and unavailable devices, use soft tfm instead= */ if (ctx->fallback) { akcipher_request_set_tfm(req, ctx->rsa.soft_tfm); @@ -834,10 +969,9 @@ static int hpre_rsa_dec(struct akcipher_request *req) if (unlikely(ret)) goto clear_all; =20 - /* success */ - ret =3D hpre_send(ctx, msg); - if (likely(!ret)) - return -EINPROGRESS; + ret =3D hpre_alg_send_message(hpre_req); + if (likely(ret =3D=3D -EINPROGRESS || ret =3D=3D -EBUSY)) + return ret; =20 clear_all: hpre_hw_data_clr_all(ctx, hpre_req, req->dst, req->src); @@ -1387,32 +1521,6 @@ static int hpre_ecdh_set_secret(struct crypto_kpp *t= fm, const void *buf, return 0; } =20 -static void hpre_ecdh_hw_data_clr_all(struct hpre_ctx *ctx, - struct hpre_asym_request *req, - struct scatterlist *dst, - struct scatterlist *src) -{ - struct device *dev =3D ctx->dev; - struct hpre_sqe *sqe =3D &req->req; - dma_addr_t dma; - - dma =3D le64_to_cpu(sqe->in); - if (unlikely(dma_mapping_error(dev, dma))) - return; - - if (src && req->src) - dma_free_coherent(dev, ctx->key_sz << 2, req->src, dma); - - dma =3D le64_to_cpu(sqe->out); - if (unlikely(dma_mapping_error(dev, dma))) - return; - - if (req->dst) - dma_free_coherent(dev, ctx->key_sz << 1, req->dst, dma); - if (dst) - dma_unmap_single(dev, dma, ctx->key_sz << 1, DMA_FROM_DEVICE); -} - static void hpre_ecdh_cb(struct hpre_ctx *ctx, void *resp) { unsigned int curve_sz =3D hpre_ecdh_get_curvesz(ctx->curve_id); @@ -1538,6 +1646,7 @@ static int hpre_ecdh_compute_value(struct kpp_request= *req) struct hpre_sqe *msg =3D &hpre_req->req; int ret; =20 + hpre_req->base =3D &req->base; ret =3D hpre_ecdh_msg_request_set(ctx, req); if (unlikely(ret)) { dev_err(dev, "failed to set ecdh request, ret =3D %d!\n", ret); @@ -1563,9 +1672,9 @@ static int hpre_ecdh_compute_value(struct kpp_request= *req) msg->dw0 =3D cpu_to_le32(le32_to_cpu(msg->dw0) | HPRE_ALG_ECC_MUL); msg->resv1 =3D ctx->enable_hpcore << HPRE_ENABLE_HPCORE_SHIFT; =20 - ret =3D hpre_send(ctx, msg); - if (likely(!ret)) - return -EINPROGRESS; + ret =3D hpre_alg_send_message(hpre_req); + if (likely(ret =3D=3D -EINPROGRESS || ret =3D=3D -EBUSY)) + return ret; =20 clear_all: hpre_ecdh_hw_data_clr_all(ctx, hpre_req, req->dst, req->src); --=20 2.43.0 From nobody Fri Jun 12 11:18:45 2026 Received: from canpmsgout03.his.huawei.com (canpmsgout03.his.huawei.com [113.46.200.218]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 908A8480340; Fri, 15 May 2026 11:47:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.218 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778845655; cv=none; b=NQxNK67LOoG4LlrkTeD40eGyhcMq2TrUdIycFwzpYnS//Iy90FF55jse1tFSHh9olDdDzy3xmXgd8iW8DuH1eNPZK7fpbAqLQ6qaP/ktH0AeH0A5QiYZX+2GlP0rF2B4pnocZEWQpsKvxQ+DQ70CGOujLjQBi7iD/8zC1tgjDEk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778845655; c=relaxed/simple; bh=yNjyEOa01z/Ohnd87fDVpZuMG/DRDsFApX0oCwlVkD4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=fYCVMH7hKCAJsmLDnTO8OkobDu/RXjja7om+k3MH+hmBVBpJEOk2mJkIdm2T/bvVTL3FodZ1Hqs5ehpywF1jDrXuuGGP6w50VJy9yh5fWnuQZJzAnzN+epU9u9SalHeEbQSr8KgEvexkq/yCPVmeUvM2a4QjVyeza6ED52eHagA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=qGSV1yof; arc=none smtp.client-ip=113.46.200.218 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="qGSV1yof" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=6ZcA8T3DZRqSLPYgddyA/JtWgUgkayMJh6YovlBnK10=; b=qGSV1yofdUjSeIN2yjtcgPD6eaH5UpA75kvbKjwvSA3Sio4kovHrG6uwNQZHst9WKIbV4R/yR oOYfUD5jmocBS08JSGVgqTenh+Yt7sehkrPsi23DtILPquJIrzWxRyVHQs4is00ESrTsA1Cz4pb JCzchkSEkOZ47A8/HSvj+dk= Received: from mail.maildlp.com (unknown [172.19.162.223]) by canpmsgout03.his.huawei.com (SkyGuard) with ESMTPS id 4gH4xv6Y5WzpSwC; Fri, 15 May 2026 19:40:19 +0800 (CST) Received: from kwepemr100008.china.huawei.com (unknown [7.202.195.119]) by mail.maildlp.com (Postfix) with ESMTPS id 13FAE40571; Fri, 15 May 2026 19:47:25 +0800 (CST) Received: from localhost.localdomain (10.50.163.32) by kwepemr100008.china.huawei.com (7.202.195.119) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Fri, 15 May 2026 19:47:24 +0800 From: ZongYu Wu To: , CC: , , , , , Subject: [PATCH] crypto: hisilicon/zip - add backlog support for zip Date: Fri, 15 May 2026 19:45:59 +0800 Message-ID: <20260515114601.2492524-2-wuzongyu1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260515114601.2492524-1-wuzongyu1@huawei.com> References: <20260515114601.2492524-1-wuzongyu1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems200001.china.huawei.com (7.221.188.67) To kwepemr100008.china.huawei.com (7.202.195.119) Content-Type: text/plain; charset="utf-8" From: Chenghai Huang When the hardware queue is busy, requests are now queued instead of being failed immediately. Queued requests are retried when earlier requests complete, which prevents transient failures under heavy load. The backlog path also provides a fallback mechanism while the hardware is temporarily unavailable, such as during device reset. Signed-off-by: Chenghai Huang Signed-off-by: Zongyu Wu --- drivers/crypto/hisilicon/zip/zip_crypto.c | 284 ++++++++++++++-------- 1 file changed, 180 insertions(+), 104 deletions(-) diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/his= ilicon/zip/zip_crypto.c index 70adde049b53..ff287251218e 100644 --- a/drivers/crypto/hisilicon/zip/zip_crypto.c +++ b/drivers/crypto/hisilicon/zip/zip_crypto.c @@ -28,6 +28,7 @@ =20 #define HZIP_ALG_DEFLATE GENMASK(5, 4) #define HZIP_ALG_LZ4 BIT(8) +#define HZIP_INVAL_REQ_ID ((u16)0xFFFF) =20 static DEFINE_MUTEX(zip_algs_lock); static unsigned int zip_available_devs; @@ -55,11 +56,11 @@ struct hisi_zip_req { dma_addr_t dma_src; dma_addr_t dma_dst; struct hisi_zip_qp_ctx *qp_ctx; + struct list_head list; u16 req_id; }; =20 struct hisi_zip_req_q { - struct hisi_zip_req *q; unsigned long *req_bitmap; spinlock_t req_lock; u16 size; @@ -135,42 +136,42 @@ static int hisi_zip_fallback_do_work(struct acomp_req= *acomp_req, bool is_decomp return ret; } =20 -static struct hisi_zip_req *hisi_zip_create_req(struct hisi_zip_qp_ctx *qp= _ctx, - struct acomp_req *req) +static int hisi_zip_create_req(struct hisi_zip_req *req) { + struct hisi_zip_qp_ctx *qp_ctx =3D req->qp_ctx; struct hisi_zip_req_q *req_q =3D &qp_ctx->req_q; - struct hisi_zip_req *q =3D req_q->q; - struct hisi_zip_req *req_cache; int req_id; =20 + /* Check whether any request is being queued */ + if (!list_empty(&qp_ctx->qp->backlog.list)) + return -EBUSY; + spin_lock(&req_q->req_lock); =20 req_id =3D find_first_zero_bit(req_q->req_bitmap, req_q->size); if (req_id >=3D req_q->size) { spin_unlock(&req_q->req_lock); dev_dbg(&qp_ctx->qp->qm->pdev->dev, "req cache is full!\n"); - return ERR_PTR(-EAGAIN); + return -EBUSY; } set_bit(req_id, req_q->req_bitmap); =20 spin_unlock(&req_q->req_lock); =20 - req_cache =3D q + req_id; - req_cache->req_id =3D req_id; - req_cache->req =3D req; - req_cache->qp_ctx =3D qp_ctx; + req->req_id =3D req_id; =20 - return req_cache; + return 0; } =20 -static void hisi_zip_remove_req(struct hisi_zip_qp_ctx *qp_ctx, - struct hisi_zip_req *req) +static void hisi_zip_remove_req(struct hisi_zip_req *req) { - struct hisi_zip_req_q *req_q =3D &qp_ctx->req_q; + struct hisi_zip_req_q *req_q =3D &req->qp_ctx->req_q; =20 spin_lock(&req_q->req_lock); clear_bit(req->req_id, req_q->req_bitmap); spin_unlock(&req_q->req_lock); + + req->req_id =3D HZIP_INVAL_REQ_ID; } =20 static void hisi_zip_fill_addr(struct hisi_zip_sqe *sqe, struct hisi_zip_r= eq *req) @@ -247,19 +248,21 @@ static void hisi_zip_fill_sqe(struct hisi_zip_ctx *ct= x, struct hisi_zip_sqe *sqe ops->fill_sqe_type(sqe, ops->sqe_type); } =20 -static int hisi_zip_do_work(struct hisi_zip_qp_ctx *qp_ctx, - struct hisi_zip_req *req) +static void hisi_zip_enqueue_backlog(struct hisi_zip_req *req) +{ + struct hisi_qp *qp =3D req->qp_ctx->qp; + + spin_lock_bh(&qp->backlog.lock); + list_add_tail(&req->list, &qp->backlog.list); + spin_unlock_bh(&qp->backlog.lock); +} + +static int hisi_zip_map_req_buffers(struct hisi_zip_req *req) { + struct hisi_zip_qp_ctx *qp_ctx =3D req->qp_ctx; struct hisi_acc_sgl_pool *pool =3D qp_ctx->sgl_pool; - struct hisi_zip_dfx *dfx =3D &qp_ctx->zip_dev->dfx; + struct device *dev =3D &qp_ctx->qp->qm->pdev->dev; struct acomp_req *a_req =3D req->req; - struct hisi_qp *qp =3D qp_ctx->qp; - struct device *dev =3D &qp->qm->pdev->dev; - struct hisi_zip_sqe zip_sqe; - int ret; - - if (unlikely(!a_req->src || !a_req->slen || !a_req->dst || !a_req->dlen)) - return -EINVAL; =20 req->hw_src =3D hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->src, pool, req->req_id << 1, &req->dma_src, @@ -274,33 +277,110 @@ static int hisi_zip_do_work(struct hisi_zip_qp_ctx *= qp_ctx, (req->req_id << 1) + 1, &req->dma_dst, DMA_FROM_DEVICE); if (IS_ERR(req->hw_dst)) { - ret =3D PTR_ERR(req->hw_dst); - dev_err(dev, "failed to map the dst buffer to hw sgl (%d)!\n", - ret); - goto err_unmap_input; + dev_err(dev, "failed to map the dst buffer to hw sgl (%ld)!\n", + PTR_ERR(req->hw_dst)); + hisi_acc_sg_buf_unmap(dev, a_req->src, req->hw_src, DMA_TO_DEVICE); + return PTR_ERR(req->hw_dst); } =20 + return 0; +} + +static void hisi_zip_unmap_req_buffers(struct hisi_zip_req *req) +{ + struct device *dev =3D &req->qp_ctx->qp->qm->pdev->dev; + struct acomp_req *a_req =3D req->req; + + hisi_acc_sg_buf_unmap(dev, a_req->dst, req->hw_dst, DMA_FROM_DEVICE); + hisi_acc_sg_buf_unmap(dev, a_req->src, req->hw_src, DMA_TO_DEVICE); +} + +static int hisi_zip_do_work(struct hisi_zip_req *req) +{ + struct hisi_zip_qp_ctx *qp_ctx =3D req->qp_ctx; + struct hisi_zip_dfx *dfx =3D &qp_ctx->zip_dev->dfx; + struct hisi_qp *qp =3D qp_ctx->qp; + struct hisi_zip_sqe zip_sqe; + int ret; + hisi_zip_fill_sqe(qp_ctx->ctx, &zip_sqe, qp_ctx->req_type, req); =20 /* send command to start a task */ - atomic64_inc(&dfx->send_cnt); ret =3D hisi_qp_send(qp, &zip_sqe); - if (unlikely(ret < 0)) { - atomic64_inc(&dfx->send_busy_cnt); - ret =3D -EAGAIN; - dev_dbg_ratelimited(dev, "failed to send request!\n"); - goto err_unmap_output; + if (likely(!ret)) { + atomic64_inc(&dfx->send_cnt); + return -EINPROGRESS; } =20 - return -EINPROGRESS; + if (ret =3D=3D -EBUSY) + atomic64_inc(&dfx->send_busy_cnt); =20 -err_unmap_output: - hisi_acc_sg_buf_unmap(dev, a_req->dst, req->hw_dst, DMA_FROM_DEVICE); -err_unmap_input: - hisi_acc_sg_buf_unmap(dev, a_req->src, req->hw_src, DMA_TO_DEVICE); return ret; } =20 +static void hisi_zip_send_backlog_soft(struct hisi_zip_qp_ctx *qp_ctx) +{ + bool is_decomp =3D qp_ctx->qp->alg_type; + struct hisi_zip_req *req, *tmp; + int ret; + + list_for_each_entry_safe(req, tmp, &qp_ctx->qp->backlog.list, list) { + list_del(&req->list); + + if (req->req_id !=3D HZIP_INVAL_REQ_ID) { + hisi_zip_unmap_req_buffers(req); + hisi_zip_remove_req(req); + } + + ret =3D hisi_zip_fallback_do_work(req->req, is_decomp); + + /* Wake up the busy thread first, then return the errno. */ + if (req->req->base.complete) { + acomp_request_complete(req->req, -EINPROGRESS); + acomp_request_complete(req->req, ret); + } + } +} + +static void hisi_zip_send_backlog(struct hisi_qp *qp) +{ + struct hisi_zip_req *req, *tmp; + int ret; + + spin_lock_bh(&qp->backlog.lock); + list_for_each_entry_safe(req, tmp, &qp->backlog.list, list) { + if (req->req_id =3D=3D HZIP_INVAL_REQ_ID) { + ret =3D hisi_zip_create_req(req); + if (ret) + continue; + + ret =3D hisi_zip_map_req_buffers(req); + if (unlikely(ret)) { + hisi_zip_remove_req(req); + hisi_zip_send_backlog_soft(req->qp_ctx); + goto unlock; + } + } + + ret =3D hisi_zip_do_work(req); + switch (ret) { + case -EINPROGRESS: + list_del(&req->list); + if (req->req->base.complete) + acomp_request_complete(req->req, -EINPROGRESS); + break; + case -EBUSY: + goto unlock; + default: + hisi_zip_send_backlog_soft(req->qp_ctx); + goto unlock; + } + } + +unlock: + spin_unlock_bh(&qp->backlog.lock); +} + static u32 hisi_zip_get_status(struct hisi_zip_sqe *sqe) { return sqe->dw3 & HZIP_BD_STATUS_M; @@ -333,73 +413,89 @@ static void hisi_zip_acomp_cb(struct hisi_qp *qp, voi= d *data) err =3D -EIO; } =20 - hisi_acc_sg_buf_unmap(dev, acomp_req->dst, req->hw_dst, DMA_FROM_DEVICE); - hisi_acc_sg_buf_unmap(dev, acomp_req->src, req->hw_src, DMA_TO_DEVICE); + hisi_zip_unmap_req_buffers(req); =20 acomp_req->dlen =3D ops->get_dstlen(sqe); + hisi_zip_remove_req(req); =20 if (acomp_req->base.complete) acomp_request_complete(acomp_req, err); =20 - hisi_zip_remove_req(qp_ctx, req); + hisi_zip_send_backlog(qp); } =20 -static int hisi_zip_acompress(struct acomp_req *acomp_req) +static int hisi_zip_do_comp(struct hisi_zip_req *req) { + struct acomp_req *acomp_req =3D req->req; struct hisi_zip_ctx *ctx =3D crypto_tfm_ctx(acomp_req->base.tfm); - struct hisi_zip_qp_ctx *qp_ctx =3D &ctx->qp_ctx[HZIP_QPC_COMP]; - struct hisi_zip_req *req; - struct device *dev; + struct hisi_qp *qp =3D req->qp_ctx->qp; int ret; =20 - if (ctx->fallback) - return hisi_zip_fallback_do_work(acomp_req, 0); - - dev =3D &qp_ctx->qp->qm->pdev->dev; + if (unlikely(!acomp_req->src || !acomp_req->slen || + !acomp_req->dst || !acomp_req->dlen)) + return -EINVAL; =20 - req =3D hisi_zip_create_req(qp_ctx, acomp_req); - if (IS_ERR(req)) - return PTR_ERR(req); + if (ctx->fallback) + return hisi_zip_fallback_do_work(acomp_req, qp->alg_type); + + ret =3D hisi_zip_create_req(req); + if (ret && (acomp_req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { + /* all req bitmaps are used add to backlog list */ + req->req_id =3D HZIP_INVAL_REQ_ID; + hisi_zip_enqueue_backlog(req); + return -EBUSY; + } else if (unlikely(ret)) { + return -ENOSPC; + } =20 - ret =3D hisi_zip_do_work(qp_ctx, req); - if (unlikely(ret !=3D -EINPROGRESS)) { - dev_info_ratelimited(dev, "failed to do compress (%d)!\n", ret); - hisi_zip_remove_req(qp_ctx, req); + ret =3D hisi_zip_map_req_buffers(req); + if (unlikely(ret)) + goto remove_req; + + ret =3D hisi_zip_do_work(req); + if (ret =3D=3D -EBUSY && (acomp_req->base.flags & CRYPTO_TFM_REQ_MAY_BACK= LOG)) { + /* hardwre busy add to backlog list */ + hisi_zip_enqueue_backlog(req); + } else if (unlikely(ret !=3D -EINPROGRESS)) { + dev_info_ratelimited(&qp->qm->pdev->dev, + "failed to do %scompress (%d)!\n", + qp->alg_type ? "de" : "", ret); + ret =3D -ENOSPC; + goto unmap_req; } =20 return ret; + +unmap_req: + hisi_zip_unmap_req_buffers(req); +remove_req: + hisi_zip_remove_req(req); + return ret; } =20 -static int hisi_zip_adecompress(struct acomp_req *acomp_req) +static int hisi_zip_acompress(struct acomp_req *acomp_req) { struct hisi_zip_ctx *ctx =3D crypto_tfm_ctx(acomp_req->base.tfm); - struct hisi_zip_qp_ctx *qp_ctx =3D &ctx->qp_ctx[HZIP_QPC_DECOMP]; - struct hisi_zip_req *req; - struct device *dev; - int ret; - - if (ctx->fallback) - return hisi_zip_fallback_do_work(acomp_req, 1); + struct hisi_zip_req *req =3D acomp_request_ctx(acomp_req); =20 - dev =3D &qp_ctx->qp->qm->pdev->dev; - - req =3D hisi_zip_create_req(qp_ctx, acomp_req); - if (IS_ERR(req)) - return PTR_ERR(req); + req->req =3D acomp_req; + req->qp_ctx =3D &ctx->qp_ctx[HZIP_QPC_COMP]; + return hisi_zip_do_comp(req); +} =20 - ret =3D hisi_zip_do_work(qp_ctx, req); - if (unlikely(ret !=3D -EINPROGRESS)) { - dev_info_ratelimited(dev, "failed to do decompress (%d)!\n", - ret); - hisi_zip_remove_req(qp_ctx, req); - } +static int hisi_zip_adecompress(struct acomp_req *acomp_req) +{ + struct hisi_zip_ctx *ctx =3D crypto_tfm_ctx(acomp_req->base.tfm); + struct hisi_zip_req *req =3D acomp_request_ctx(acomp_req); =20 - return ret; + req->req =3D acomp_req; + req->qp_ctx =3D &ctx->qp_ctx[HZIP_QPC_DECOMP]; + return hisi_zip_do_comp(req); } =20 static int hisi_zip_decompress(struct acomp_req *acomp_req) { - return hisi_zip_fallback_do_work(acomp_req, 1); + return hisi_zip_fallback_do_work(acomp_req, HZIP_ALG_TYPE_DECOMP); } =20 static const struct hisi_zip_sqe_ops hisi_zip_ops =3D { @@ -463,7 +559,7 @@ static int hisi_zip_create_req_q(struct hisi_zip_ctx *c= tx) { u16 q_depth =3D ctx->qp_ctx[0].qp->sq_depth; struct hisi_zip_req_q *req_q; - int i, ret; + int i; =20 for (i =3D 0; i < HZIP_CTX_Q_NUM; i++) { req_q =3D &ctx->qp_ctx[i].req_q; @@ -471,43 +567,21 @@ static int hisi_zip_create_req_q(struct hisi_zip_ctx = *ctx) =20 req_q->req_bitmap =3D bitmap_zalloc(req_q->size, GFP_KERNEL); if (!req_q->req_bitmap) { - ret =3D -ENOMEM; - if (i =3D=3D 0) - return ret; - - goto err_free_comp_q; + bitmap_free(ctx->qp_ctx[HZIP_QPC_COMP].req_q.req_bitmap); + return -ENOMEM; } spin_lock_init(&req_q->req_lock); - - req_q->q =3D kzalloc_objs(struct hisi_zip_req, req_q->size); - if (!req_q->q) { - ret =3D -ENOMEM; - if (i =3D=3D 0) - goto err_free_comp_bitmap; - else - goto err_free_decomp_bitmap; - } } =20 return 0; - -err_free_decomp_bitmap: - bitmap_free(ctx->qp_ctx[HZIP_QPC_DECOMP].req_q.req_bitmap); -err_free_comp_q: - kfree(ctx->qp_ctx[HZIP_QPC_COMP].req_q.q); -err_free_comp_bitmap: - bitmap_free(ctx->qp_ctx[HZIP_QPC_COMP].req_q.req_bitmap); - return ret; } =20 static void hisi_zip_release_req_q(struct hisi_zip_ctx *ctx) { int i; =20 - for (i =3D 0; i < HZIP_CTX_Q_NUM; i++) { - kfree(ctx->qp_ctx[i].req_q.q); + for (i =3D 0; i < HZIP_CTX_Q_NUM; i++) bitmap_free(ctx->qp_ctx[i].req_q.req_bitmap); - } } =20 static int hisi_zip_create_sgl_pool(struct hisi_zip_ctx *ctx) @@ -620,6 +694,7 @@ static struct acomp_alg hisi_zip_acomp_deflate =3D { .cra_module =3D THIS_MODULE, .cra_priority =3D HZIP_ALG_PRIORITY, .cra_ctxsize =3D sizeof(struct hisi_zip_ctx), + .cra_reqsize =3D sizeof(struct hisi_zip_req), } }; =20 @@ -658,6 +733,7 @@ static struct acomp_alg hisi_zip_acomp_lz4 =3D { .cra_module =3D THIS_MODULE, .cra_priority =3D HZIP_ALG_PRIORITY, .cra_ctxsize =3D sizeof(struct hisi_zip_ctx), + .cra_reqsize =3D sizeof(struct hisi_zip_req), } }; =20 --=20 2.43.0