]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
crypto: hisilicon - consolidate qp creation and start in hisi_qm_alloc_qps_node
authorChenghai Huang <huangchenghai2@huawei.com>
Thu, 18 Dec 2025 13:44:47 +0000 (21:44 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 16 Jan 2026 06:02:06 +0000 (14:02 +0800)
Consolidate the creation and start of qp into the function
hisi_qm_alloc_qps_node. This change eliminates the need for
each module to perform these steps in two separate phases
(creation and start).

Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com>
Signed-off-by: Weili Qian <qianweili@huawei.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/hisilicon/hpre/hpre_crypto.c
drivers/crypto/hisilicon/qm.c
drivers/crypto/hisilicon/sec2/sec_crypto.c
drivers/crypto/hisilicon/zip/zip_crypto.c
include/linux/hisi_acc_qm.h

index 220022ae7afb610a965fdf8f01828a32840c6516..f410e610eabaa086c1ddaa1baa7c722450915635 100644 (file)
@@ -156,27 +156,6 @@ static void hpre_dfx_add_req_time(struct hpre_asym_request *hpre_req)
                ktime_get_ts64(&hpre_req->req_time);
 }
 
-static struct hisi_qp *hpre_get_qp_and_start(u8 type)
-{
-       struct hisi_qp *qp;
-       int ret;
-
-       qp = hpre_create_qp(type);
-       if (!qp) {
-               pr_err("Can not create hpre qp!\n");
-               return ERR_PTR(-ENODEV);
-       }
-
-       ret = hisi_qm_start_qp(qp, 0);
-       if (ret < 0) {
-               hisi_qm_free_qps(&qp, 1);
-               pci_err(qp->qm->pdev, "Can not start qp!\n");
-               return ERR_PTR(-EINVAL);
-       }
-
-       return qp;
-}
-
 static int hpre_get_data_dma_addr(struct hpre_asym_request *hpre_req,
                                  struct scatterlist *data, unsigned int len,
                                  int is_src, dma_addr_t *tmp)
@@ -316,9 +295,8 @@ static int hpre_alg_res_post_hf(struct hpre_ctx *ctx, struct hpre_sqe *sqe,
 
 static void hpre_ctx_clear(struct hpre_ctx *ctx, bool is_clear_all)
 {
-       if (is_clear_all) {
+       if (is_clear_all)
                hisi_qm_free_qps(&ctx->qp, 1);
-       }
 
        ctx->crt_g2_mode = false;
        ctx->key_sz = 0;
@@ -403,11 +381,10 @@ static int hpre_ctx_init(struct hpre_ctx *ctx, u8 type)
        struct hisi_qp *qp;
        struct hpre *hpre;
 
-       qp = hpre_get_qp_and_start(type);
-       if (IS_ERR(qp))
-               return PTR_ERR(qp);
+       qp = hpre_create_qp(type);
+       if (!qp)
+               return -ENODEV;
 
-       qp->qp_ctx = ctx;
        qp->req_cb = hpre_alg_cb;
        ctx->qp = qp;
        ctx->dev = &qp->qm->pdev->dev;
@@ -597,9 +574,6 @@ static void hpre_dh_clear_ctx(struct hpre_ctx *ctx, bool is_clear_all)
        struct device *dev = ctx->dev;
        unsigned int sz = ctx->key_sz;
 
-       if (is_clear_all)
-               hisi_qm_stop_qp(ctx->qp);
-
        if (ctx->dh.g) {
                dma_free_coherent(dev, sz, ctx->dh.g, ctx->dh.dma_g);
                ctx->dh.g = NULL;
@@ -940,9 +914,6 @@ static void hpre_rsa_clear_ctx(struct hpre_ctx *ctx, bool is_clear_all)
        unsigned int half_key_sz = ctx->key_sz >> 1;
        struct device *dev = ctx->dev;
 
-       if (is_clear_all)
-               hisi_qm_stop_qp(ctx->qp);
-
        if (ctx->rsa.pubkey) {
                dma_free_coherent(dev, ctx->key_sz << 1,
                                  ctx->rsa.pubkey, ctx->rsa.dma_pubkey);
@@ -1112,9 +1083,6 @@ static void hpre_ecc_clear_ctx(struct hpre_ctx *ctx, bool is_clear_all)
        unsigned int sz = ctx->key_sz;
        unsigned int shift = sz << 1;
 
-       if (is_clear_all)
-               hisi_qm_stop_qp(ctx->qp);
-
        if (ctx->ecdh.p) {
                /* ecdh: p->a->k->b */
                memzero_explicit(ctx->ecdh.p + shift, sz);
index 0f5e39884e4a3808775b20f1bac1256a6394177e..b8e59f99f7007cc76c15babffbbadf012f08d736 100644 (file)
@@ -3553,6 +3553,14 @@ void hisi_qm_dev_err_uninit(struct hisi_qm *qm)
 }
 EXPORT_SYMBOL_GPL(hisi_qm_dev_err_uninit);
 
+static void qm_release_qp_nolock(struct hisi_qp *qp)
+{
+       struct hisi_qm *qm = qp->qm;
+
+       qm->qp_in_used--;
+       idr_remove(&qm->qp_idr, qp->qp_id);
+}
+
 /**
  * hisi_qm_free_qps() - free multiple queue pairs.
  * @qps: The queue pairs need to be freed.
@@ -3565,8 +3573,15 @@ void hisi_qm_free_qps(struct hisi_qp **qps, int qp_num)
        if (!qps || qp_num <= 0)
                return;
 
-       for (i = qp_num - 1; i >= 0; i--)
-               hisi_qm_release_qp(qps[i]);
+       down_write(&qps[0]->qm->qps_lock);
+
+       for (i = qp_num - 1; i >= 0; i--) {
+               qm_stop_qp_nolock(qps[i]);
+               qm_release_qp_nolock(qps[i]);
+       }
+
+       up_write(&qps[0]->qm->qps_lock);
+       qm_pm_put_sync(qps[0]->qm);
 }
 EXPORT_SYMBOL_GPL(hisi_qm_free_qps);
 
@@ -3580,6 +3595,43 @@ static void free_list(struct list_head *head)
        }
 }
 
+static int qm_get_and_start_qp(struct hisi_qm *qm, int qp_num, struct hisi_qp **qps, u8 *alg_type)
+{
+       int i, ret;
+
+       ret = qm_pm_get_sync(qm);
+       if (ret)
+               return ret;
+
+       down_write(&qm->qps_lock);
+       for (i = 0; i < qp_num; i++) {
+               qps[i] = qm_create_qp_nolock(qm, alg_type[i]);
+               if (IS_ERR(qps[i])) {
+                       ret = -ENODEV;
+                       goto stop_and_free;
+               }
+
+               ret = qm_start_qp_nolock(qps[i], 0);
+               if (ret) {
+                       qm_release_qp_nolock(qps[i]);
+                       goto stop_and_free;
+               }
+       }
+       up_write(&qm->qps_lock);
+
+       return 0;
+
+stop_and_free:
+       for (i--; i >= 0; i--) {
+               qm_stop_qp_nolock(qps[i]);
+               qm_release_qp_nolock(qps[i]);
+       }
+       up_write(&qm->qps_lock);
+       qm_pm_put_sync(qm);
+
+       return ret;
+}
+
 static int hisi_qm_sort_devices(int node, struct list_head *head,
                                struct hisi_qm_list *qm_list)
 {
@@ -3633,7 +3685,6 @@ int hisi_qm_alloc_qps_node(struct hisi_qm_list *qm_list, int qp_num,
        struct hisi_qm_resource *tmp;
        int ret = -ENODEV;
        LIST_HEAD(head);
-       int i;
 
        if (!qps || !qm_list || qp_num <= 0)
                return -EINVAL;
@@ -3645,18 +3696,9 @@ int hisi_qm_alloc_qps_node(struct hisi_qm_list *qm_list, int qp_num,
        }
 
        list_for_each_entry(tmp, &head, list) {
-               for (i = 0; i < qp_num; i++) {
-                       qps[i] = hisi_qm_create_qp(tmp->qm, alg_type[i]);
-                       if (IS_ERR(qps[i])) {
-                               hisi_qm_free_qps(qps, i);
-                               break;
-                       }
-               }
-
-               if (i == qp_num) {
-                       ret = 0;
+               ret = qm_get_and_start_qp(tmp->qm, qp_num, qps, alg_type);
+               if (!ret)
                        break;
-               }
        }
 
        mutex_unlock(&qm_list->lock);
index 364bd69c6088334ce6bd74272b2fd88108159387..d09d081f42dc78d75a75d221bd38510aecf850b0 100644 (file)
@@ -626,7 +626,6 @@ static int sec_create_qp_ctx(struct sec_ctx *ctx, int qp_ctx_id)
 
        qp_ctx = &ctx->qp_ctx[qp_ctx_id];
        qp = ctx->qps[qp_ctx_id];
-       qp->qp_ctx = qp_ctx;
        qp_ctx->qp = qp;
        qp_ctx->ctx = ctx;
 
@@ -644,14 +643,8 @@ static int sec_create_qp_ctx(struct sec_ctx *ctx, int qp_ctx_id)
        if (ret)
                goto err_destroy_idr;
 
-       ret = hisi_qm_start_qp(qp, 0);
-       if (ret < 0)
-               goto err_resource_free;
-
        return 0;
 
-err_resource_free:
-       sec_free_qp_ctx_resource(ctx, qp_ctx);
 err_destroy_idr:
        idr_destroy(&qp_ctx->req_idr);
        return ret;
@@ -660,7 +653,6 @@ err_destroy_idr:
 static void sec_release_qp_ctx(struct sec_ctx *ctx,
                               struct sec_qp_ctx *qp_ctx)
 {
-       hisi_qm_stop_qp(qp_ctx->qp);
        sec_free_qp_ctx_resource(ctx, qp_ctx);
        idr_destroy(&qp_ctx->req_idr);
 }
index 2f9035c016f3ffd49eb4646815dcfb34ac8980a5..108ab667131df732ecda84b406dd07f68cdb1f7f 100644 (file)
@@ -352,32 +352,6 @@ static int hisi_zip_adecompress(struct acomp_req *acomp_req)
        return ret;
 }
 
-static int hisi_zip_start_qp(struct hisi_qp *qp, struct hisi_zip_qp_ctx *qp_ctx,
-                            int alg_type, int req_type)
-{
-       struct device *dev = &qp->qm->pdev->dev;
-       int ret;
-
-       qp->alg_type = alg_type;
-       qp->qp_ctx = qp_ctx;
-
-       ret = hisi_qm_start_qp(qp, 0);
-       if (ret < 0) {
-               dev_err(dev, "failed to start qp (%d)!\n", ret);
-               return ret;
-       }
-
-       qp_ctx->qp = qp;
-
-       return 0;
-}
-
-static void hisi_zip_release_qp(struct hisi_zip_qp_ctx *qp_ctx)
-{
-       hisi_qm_stop_qp(qp_ctx->qp);
-       hisi_qm_free_qps(&qp_ctx->qp, 1);
-}
-
 static const struct hisi_zip_sqe_ops hisi_zip_ops = {
        .sqe_type               = 0x3,
        .fill_addr              = hisi_zip_fill_addr,
@@ -396,7 +370,7 @@ static int hisi_zip_ctx_init(struct hisi_zip_ctx *hisi_zip_ctx, u8 req_type, int
        struct hisi_zip_qp_ctx *qp_ctx;
        u8 alg_type[HZIP_CTX_Q_NUM];
        struct hisi_zip *hisi_zip;
-       int ret, i, j;
+       int ret, i;
 
        /* alg_type = 0 for compress, 1 for decompress in hw sqe */
        for (i = 0; i < HZIP_CTX_Q_NUM; i++)
@@ -413,17 +387,9 @@ static int hisi_zip_ctx_init(struct hisi_zip_ctx *hisi_zip_ctx, u8 req_type, int
        for (i = 0; i < HZIP_CTX_Q_NUM; i++) {
                qp_ctx = &hisi_zip_ctx->qp_ctx[i];
                qp_ctx->ctx = hisi_zip_ctx;
-               ret = hisi_zip_start_qp(qps[i], qp_ctx, i, req_type);
-               if (ret) {
-                       for (j = i - 1; j >= 0; j--)
-                               hisi_qm_stop_qp(hisi_zip_ctx->qp_ctx[j].qp);
-
-                       hisi_qm_free_qps(qps, HZIP_CTX_Q_NUM);
-                       return ret;
-               }
-
                qp_ctx->zip_dev = hisi_zip;
                qp_ctx->req_type = req_type;
+               qp_ctx->qp = qps[i];
        }
 
        hisi_zip_ctx->ops = &hisi_zip_ops;
@@ -433,10 +399,13 @@ static int hisi_zip_ctx_init(struct hisi_zip_ctx *hisi_zip_ctx, u8 req_type, int
 
 static void hisi_zip_ctx_exit(struct hisi_zip_ctx *hisi_zip_ctx)
 {
+       struct hisi_qp *qps[HZIP_CTX_Q_NUM] = { NULL };
        int i;
 
        for (i = 0; i < HZIP_CTX_Q_NUM; i++)
-               hisi_zip_release_qp(&hisi_zip_ctx->qp_ctx[i]);
+               qps[i] = hisi_zip_ctx->qp_ctx[i].qp;
+
+       hisi_qm_free_qps(qps, HZIP_CTX_Q_NUM);
 }
 
 static int hisi_zip_create_req_q(struct hisi_zip_ctx *ctx)
index ef4d3a79bcb706f3719b1fc785ec2d22d8ed1b27..59f9858049586adcf35f831f8503512f91b7ff14 100644 (file)
@@ -466,7 +466,6 @@ struct hisi_qp {
 
        struct hisi_qp_status qp_status;
        struct hisi_qp_ops *hw_ops;
-       void *qp_ctx;
        void (*req_cb)(struct hisi_qp *qp, void *data);
        void (*event_cb)(struct hisi_qp *qp);