crypto: hisilicon/zip - Use hisi_qm_alloc_qps_node() when init ctx
authorShukun Tan <tanshukun1@huawei.com>
Tue, 10 Mar 2020 08:42:50 +0000 (16:42 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 20 Mar 2020 03:36:50 +0000 (14:36 +1100)
Encapsulate hisi_qm_alloc_qps_node() to new interface to replace
find_zip_device(), which will fix the bug of creating QP failure
especially in multi-thread scenario.

Signed-off-by: Shukun Tan <tanshukun1@huawei.com>
Reviewed-by: Zhou Wang <wangzhou1@hisilicon.com>
Reviewed-by: Zaibo Xu <xuzaibo@huawei.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/hisilicon/zip/zip.h
drivers/crypto/hisilicon/zip/zip_crypto.c
drivers/crypto/hisilicon/zip/zip_main.c

index bc1db26..82dc6f8 100644 (file)
@@ -68,7 +68,7 @@ struct hisi_zip_sqe {
        u32 rsvd1[4];
 };
 
-struct hisi_zip *find_zip_device(int node);
+int zip_create_qps(struct hisi_qp **qps, int ctx_num);
 int hisi_zip_register_to_crypto(void);
 void hisi_zip_unregister_from_crypto(void);
 #endif
index 9815d5e..369ec32 100644 (file)
@@ -132,29 +132,25 @@ static void hisi_zip_fill_sqe(struct hisi_zip_sqe *sqe, u8 req_type,
        sqe->dest_addr_h = upper_32_bits(d_addr);
 }
 
-static int hisi_zip_create_qp(struct hisi_qm *qm, struct hisi_zip_qp_ctx *ctx,
-                             int alg_type, int req_type)
+static int hisi_zip_start_qp(struct hisi_qp *qp, struct hisi_zip_qp_ctx *ctx,
+                            int alg_type, int req_type)
 {
-       struct hisi_qp *qp;
+       struct device *dev = &qp->qm->pdev->dev;
        int ret;
 
-       qp = hisi_qm_create_qp(qm, alg_type);
-       if (IS_ERR(qp))
-               return PTR_ERR(qp);
-
        qp->req_type = req_type;
+       qp->alg_type = alg_type;
        qp->qp_ctx = ctx;
-       ctx->qp = qp;
 
        ret = hisi_qm_start_qp(qp, 0);
-       if (ret < 0)
-               goto err_release_qp;
+       if (ret < 0) {
+               dev_err(dev, "start qp failed!\n");
+               return ret;
+       }
 
-       return 0;
+       ctx->qp = qp;
 
-err_release_qp:
-       hisi_qm_release_qp(qp);
-       return ret;
+       return 0;
 }
 
 static void hisi_zip_release_qp(struct hisi_zip_qp_ctx *ctx)
@@ -165,34 +161,34 @@ static void hisi_zip_release_qp(struct hisi_zip_qp_ctx *ctx)
 
 static int hisi_zip_ctx_init(struct hisi_zip_ctx *hisi_zip_ctx, u8 req_type)
 {
+       struct hisi_qp *qps[HZIP_CTX_Q_NUM] = { NULL };
        struct hisi_zip *hisi_zip;
-       struct hisi_qm *qm;
        int ret, i, j;
 
-       /* find the proper zip device */
-       hisi_zip = find_zip_device(cpu_to_node(smp_processor_id()));
-       if (!hisi_zip) {
-               pr_err("Failed to find a proper ZIP device!\n");
+       ret = zip_create_qps(qps, HZIP_CTX_Q_NUM);
+       if (ret) {
+               pr_err("Can not create zip qps!\n");
                return -ENODEV;
        }
-       qm = &hisi_zip->qm;
+
+       hisi_zip = container_of(qps[0]->qm, struct hisi_zip, qm);
 
        for (i = 0; i < HZIP_CTX_Q_NUM; i++) {
                /* alg_type = 0 for compress, 1 for decompress in hw sqe */
-               ret = hisi_zip_create_qp(qm, &hisi_zip_ctx->qp_ctx[i], i,
-                                        req_type);
-               if (ret)
-                       goto err;
+               ret = hisi_zip_start_qp(qps[i], &hisi_zip_ctx->qp_ctx[i], 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;
+               }
 
                hisi_zip_ctx->qp_ctx[i].zip_dev = hisi_zip;
        }
 
        return 0;
-err:
-       for (j = i - 1; j >= 0; j--)
-               hisi_zip_release_qp(&hisi_zip_ctx->qp_ctx[j]);
-
-       return ret;
 }
 
 static void hisi_zip_ctx_exit(struct hisi_zip_ctx *hisi_zip_ctx)
index 25a3112..fcc85d2 100644 (file)
 
 static const char hisi_zip_name[] = "hisi_zip";
 static struct dentry *hzip_debugfs_root;
-static LIST_HEAD(hisi_zip_list);
-static DEFINE_MUTEX(hisi_zip_list_lock);
-
-struct hisi_zip_resource {
-       struct hisi_zip *hzip;
-       int distance;
-       struct list_head list;
-};
-
-static void free_list(struct list_head *head)
-{
-       struct hisi_zip_resource *res, *tmp;
-
-       list_for_each_entry_safe(res, tmp, head, list) {
-               list_del(&res->list);
-               kfree(res);
-       }
-}
-
-struct hisi_zip *find_zip_device(int node)
-{
-       struct hisi_zip_resource *res, *tmp;
-       struct hisi_zip *ret = NULL;
-       struct hisi_zip *hisi_zip;
-       struct list_head *n;
-       struct device *dev;
-       LIST_HEAD(head);
-
-       mutex_lock(&hisi_zip_list_lock);
-
-       if (IS_ENABLED(CONFIG_NUMA)) {
-               list_for_each_entry(hisi_zip, &hisi_zip_list, list) {
-                       res = kzalloc(sizeof(*res), GFP_KERNEL);
-                       if (!res)
-                               goto err;
-
-                       dev = &hisi_zip->qm.pdev->dev;
-                       res->hzip = hisi_zip;
-                       res->distance = node_distance(dev_to_node(dev), node);
-
-                       n = &head;
-                       list_for_each_entry(tmp, &head, list) {
-                               if (res->distance < tmp->distance) {
-                                       n = &tmp->list;
-                                       break;
-                               }
-                       }
-                       list_add_tail(&res->list, n);
-               }
-
-               list_for_each_entry(tmp, &head, list) {
-                       if (hisi_qm_get_free_qp_num(&tmp->hzip->qm)) {
-                               ret = tmp->hzip;
-                               break;
-                       }
-               }
-
-               free_list(&head);
-       } else {
-               ret = list_first_entry(&hisi_zip_list, struct hisi_zip, list);
-       }
-
-       mutex_unlock(&hisi_zip_list_lock);
-
-       return ret;
-
-err:
-       free_list(&head);
-       mutex_unlock(&hisi_zip_list_lock);
-       return NULL;
-}
+static struct hisi_qm_list zip_devices;
 
 struct hisi_zip_hw_error {
        u32 int_msk;
@@ -313,18 +243,11 @@ static const struct pci_device_id hisi_zip_dev_ids[] = {
 };
 MODULE_DEVICE_TABLE(pci, hisi_zip_dev_ids);
 
-static inline void hisi_zip_add_to_list(struct hisi_zip *hisi_zip)
+int zip_create_qps(struct hisi_qp **qps, int qp_num)
 {
-       mutex_lock(&hisi_zip_list_lock);
-       list_add_tail(&hisi_zip->list, &hisi_zip_list);
-       mutex_unlock(&hisi_zip_list_lock);
-}
+       int node = cpu_to_node(smp_processor_id());
 
-static inline void hisi_zip_remove_from_list(struct hisi_zip *hisi_zip)
-{
-       mutex_lock(&hisi_zip_list_lock);
-       list_del(&hisi_zip->list);
-       mutex_unlock(&hisi_zip_list_lock);
+       return hisi_qm_alloc_qps_node(&zip_devices, qp_num, 0, node, qps);
 }
 
 static void hisi_zip_set_user_domain_and_cache(struct hisi_zip *hisi_zip)
@@ -891,7 +814,7 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (ret)
                dev_err(&pdev->dev, "Failed to init debugfs (%d)!\n", ret);
 
-       hisi_zip_add_to_list(hisi_zip);
+       hisi_qm_add_to_list(qm, &zip_devices);
 
        if (qm->uacce) {
                ret = uacce_register(qm->uacce);
@@ -908,7 +831,7 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        return 0;
 
 err_remove_from_list:
-       hisi_zip_remove_from_list(hisi_zip);
+       hisi_qm_del_from_list(qm, &zip_devices);
        hisi_zip_debugfs_exit(hisi_zip);
        hisi_qm_stop(qm);
 err_qm_uninit:
@@ -937,7 +860,7 @@ static void hisi_zip_remove(struct pci_dev *pdev)
 
        hisi_qm_dev_err_uninit(qm);
        hisi_qm_uninit(qm);
-       hisi_zip_remove_from_list(hisi_zip);
+       hisi_qm_del_from_list(qm, &zip_devices);
 }
 
 static const struct pci_error_handlers hisi_zip_err_handler = {
@@ -971,6 +894,7 @@ static int __init hisi_zip_init(void)
 {
        int ret;
 
+       hisi_qm_init_list(&zip_devices);
        hisi_zip_register_debugfs();
 
        ret = pci_register_driver(&hisi_zip_pci_driver);