]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
crypto: hisilicon/zip - support fallback for zip
authorChenghai Huang <huangchenghai2@huawei.com>
Thu, 18 Dec 2025 13:44:50 +0000 (21:44 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 16 Jan 2026 06:02:06 +0000 (14:02 +0800)
When the hardware queue resource busy(no shareable queue)
or memery alloc fail in initialization of acomp_alg, use
soft algorithm to complete the work.

Fixes: 1a9e6f59caee ("crypto: hisilicon/zip - remove zlib and gzip")
Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/hisilicon/Kconfig
drivers/crypto/hisilicon/zip/zip_crypto.c

index 4835bdebdbb381df73c65ae20cceea210eccc314..a0cb1a8186ac9da439f17aa294211f2e773126bc 100644 (file)
@@ -57,6 +57,7 @@ config CRYPTO_DEV_HISI_ZIP
        depends on UACCE || UACCE=n
        depends on ACPI
        select CRYPTO_DEV_HISI_QM
+       select CRYPTO_DEFLATE
        help
          Support for HiSilicon ZIP Driver
 
index 108ab667131df732ecda84b406dd07f68cdb1f7f..e140d4f8afe0e80089936bd69b629884a2203786 100644 (file)
@@ -84,6 +84,7 @@ struct hisi_zip_sqe_ops {
 struct hisi_zip_ctx {
        struct hisi_zip_qp_ctx qp_ctx[HZIP_CTX_Q_NUM];
        const struct hisi_zip_sqe_ops *ops;
+       bool fallback;
 };
 
 static int sgl_sge_nr_set(const char *val, const struct kernel_param *kp)
@@ -110,6 +111,24 @@ static u16 sgl_sge_nr = HZIP_SGL_SGE_NR;
 module_param_cb(sgl_sge_nr, &sgl_sge_nr_ops, &sgl_sge_nr, 0444);
 MODULE_PARM_DESC(sgl_sge_nr, "Number of sge in sgl(1-255)");
 
+static int hisi_zip_fallback_do_work(struct acomp_req *acomp_req, bool is_decompress)
+{
+       ACOMP_FBREQ_ON_STACK(fbreq, acomp_req);
+       int ret;
+
+       if (!is_decompress)
+               ret = crypto_acomp_compress(fbreq);
+       else
+               ret = crypto_acomp_decompress(fbreq);
+       if (ret) {
+               pr_err("failed to do fallback work, ret=%d\n", ret);
+               return ret;
+       }
+
+       acomp_req->dlen = fbreq->dlen;
+       return ret;
+}
+
 static struct hisi_zip_req *hisi_zip_create_req(struct hisi_zip_qp_ctx *qp_ctx,
                                                struct acomp_req *req)
 {
@@ -313,10 +332,15 @@ static int hisi_zip_acompress(struct acomp_req *acomp_req)
 {
        struct hisi_zip_ctx *ctx = crypto_tfm_ctx(acomp_req->base.tfm);
        struct hisi_zip_qp_ctx *qp_ctx = &ctx->qp_ctx[HZIP_QPC_COMP];
-       struct device *dev = &qp_ctx->qp->qm->pdev->dev;
        struct hisi_zip_req *req;
+       struct device *dev;
        int ret;
 
+       if (ctx->fallback)
+               return hisi_zip_fallback_do_work(acomp_req, 0);
+
+       dev = &qp_ctx->qp->qm->pdev->dev;
+
        req = hisi_zip_create_req(qp_ctx, acomp_req);
        if (IS_ERR(req))
                return PTR_ERR(req);
@@ -334,10 +358,15 @@ static int hisi_zip_adecompress(struct acomp_req *acomp_req)
 {
        struct hisi_zip_ctx *ctx = crypto_tfm_ctx(acomp_req->base.tfm);
        struct hisi_zip_qp_ctx *qp_ctx = &ctx->qp_ctx[HZIP_QPC_DECOMP];
-       struct device *dev = &qp_ctx->qp->qm->pdev->dev;
        struct hisi_zip_req *req;
+       struct device *dev;
        int ret;
 
+       if (ctx->fallback)
+               return hisi_zip_fallback_do_work(acomp_req, 1);
+
+       dev = &qp_ctx->qp->qm->pdev->dev;
+
        req = hisi_zip_create_req(qp_ctx, acomp_req);
        if (IS_ERR(req))
                return PTR_ERR(req);
@@ -515,7 +544,7 @@ static int hisi_zip_acomp_init(struct crypto_acomp *tfm)
        ret = hisi_zip_ctx_init(ctx, COMP_NAME_TO_TYPE(alg_name), tfm->base.node);
        if (ret) {
                pr_err("failed to init ctx (%d)!\n", ret);
-               return ret;
+               goto switch_to_soft;
        }
 
        dev = &ctx->qp_ctx[0].qp->qm->pdev->dev;
@@ -540,16 +569,20 @@ err_release_req_q:
        hisi_zip_release_req_q(ctx);
 err_ctx_exit:
        hisi_zip_ctx_exit(ctx);
-       return ret;
+switch_to_soft:
+       ctx->fallback = true;
+       return 0;
 }
 
 static void hisi_zip_acomp_exit(struct crypto_acomp *tfm)
 {
        struct hisi_zip_ctx *ctx = crypto_tfm_ctx(&tfm->base);
 
-       hisi_zip_release_sgl_pool(ctx);
-       hisi_zip_release_req_q(ctx);
-       hisi_zip_ctx_exit(ctx);
+       if (!ctx->fallback) {
+               hisi_zip_release_sgl_pool(ctx);
+               hisi_zip_release_req_q(ctx);
+               hisi_zip_ctx_exit(ctx);
+       }
 }
 
 static struct acomp_alg hisi_zip_acomp_deflate = {
@@ -560,7 +593,8 @@ static struct acomp_alg hisi_zip_acomp_deflate = {
        .base                   = {
                .cra_name               = "deflate",
                .cra_driver_name        = "hisi-deflate-acomp",
-               .cra_flags              = CRYPTO_ALG_ASYNC,
+               .cra_flags              = CRYPTO_ALG_ASYNC |
+                                         CRYPTO_ALG_NEED_FALLBACK,
                .cra_module             = THIS_MODULE,
                .cra_priority           = HZIP_ALG_PRIORITY,
                .cra_ctxsize            = sizeof(struct hisi_zip_ctx),