From f16cf29131d9be70584b7a8c3f63a97ebd4a4003 Mon Sep 17 00:00:00 2001 From: zhangwei Date: Fri, 9 Aug 2019 21:00:28 +0800 Subject: [PATCH] ACC: fixup sec2 create multi crypt disk failed problem driver inclusion category: bugfix bugzilla: NA CVE: NA Feature or Bugfix:Bugfix Signed-off-by: Zhangwei Reviewed-by: hucheng.hu Signed-off-by: lingmingqiang Reviewed-by: lingmingqiang Reviewed-by: Yang Yingliang Signed-off-by: Yang Yingliang --- drivers/crypto/hisilicon/sec2/sec.h | 2 + drivers/crypto/hisilicon/sec2/sec_crypto.c | 4 ++ drivers/crypto/hisilicon/sec2/sec_main.c | 57 +++++++++++++++++++--- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h index b22b9830a677..633fa52166d4 100644 --- a/drivers/crypto/hisilicon/sec2/sec.h +++ b/drivers/crypto/hisilicon/sec2/sec.h @@ -50,6 +50,8 @@ struct hisi_sec { struct hisi_sec_dfx sec_dfx; struct hisi_sec_ctrl *ctrl; struct dma_pool *sgl_pool; + struct mutex *hisi_sec_list_lock; + int q_ref; int ctx_q_num; int fusion_limit; int fusion_tmout_usec; diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c index 4fd35360070d..d5f441456567 100644 --- a/drivers/crypto/hisilicon/sec2/sec_crypto.c +++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c @@ -446,6 +446,10 @@ static void hisi_sec_cipher_ctx_exit(struct crypto_skcipher *tfm) hisi_sec_release_qp_ctx(&ctx->qp_ctx[i]); kfree(ctx->qp_ctx); + + mutex_lock(ctx->sec->hisi_sec_list_lock); + ctx->sec->q_ref -= ctx->sec->ctx_q_num; + mutex_unlock(ctx->sec->hisi_sec_list_lock); } static void hisi_sec_req_cb(struct hisi_qp *qp, void *resp) diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c index 941aef422298..9c2dfdfa6918 100644 --- a/drivers/crypto/hisilicon/sec2/sec_main.c +++ b/drivers/crypto/hisilicon/sec2/sec_main.c @@ -100,28 +100,68 @@ static const char hisi_sec_name[] = "hisi_sec"; static atomic_t hisi_sec_ref = {0}; static struct dentry *hsec_debugfs_root; +static u32 pf_q_num = HSEC_PF_DEF_Q_NUM; +static struct workqueue_struct *sec_wq; + LIST_HEAD(hisi_sec_list); DEFINE_MUTEX(hisi_sec_list_lock); -static struct workqueue_struct *sec_wq; +struct hisi_sec_resource { + struct hisi_sec *hsec; + int distance; + struct list_head list; +}; + +static void free_list(struct list_head *head) +{ + struct hisi_sec_resource *res, *tmp; + + list_for_each_entry_safe(res, tmp, head, list) { + list_del(&res->list); + kfree(res); + } +} struct hisi_sec *find_sec_device(int node) { struct hisi_sec *ret = NULL; #ifdef CONFIG_NUMA + struct hisi_sec_resource *res, *tmp; struct hisi_sec *hisi_sec; - int min_distance = 100; + struct list_head *n; struct device *dev; + LIST_HEAD(head); mutex_lock(&hisi_sec_list_lock); list_for_each_entry(hisi_sec, &hisi_sec_list, list) { + res = kzalloc(sizeof(*res), GFP_KERNEL); + if (!res) + goto err; + dev = &hisi_sec->qm.pdev->dev; - if (node_distance(dev->numa_node, node) < min_distance) { - ret = hisi_sec; - min_distance = node_distance(dev->numa_node, node); + res->hsec = hisi_sec; + res->distance = node_distance(dev->numa_node, 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 (tmp->hsec->q_ref + tmp->hsec->ctx_q_num <= pf_q_num) { + tmp->hsec->q_ref += tmp->hsec->ctx_q_num; + ret = tmp->hsec; + break; } } + + free_list(&head); #else mutex_lock(&hisi_sec_list_lock); @@ -130,6 +170,10 @@ struct hisi_sec *find_sec_device(int node) mutex_unlock(&hisi_sec_list_lock); return ret; + +err: + free_list(&head); + return NULL; } struct hisi_sec_hw_error { @@ -267,7 +311,6 @@ static const struct kernel_param_ops uacce_mode_ops = { .get = param_get_int, }; -static u32 pf_q_num = HSEC_PF_DEF_Q_NUM; module_param_cb(pf_q_num, &pf_q_num_ops, &pf_q_num, 0444); MODULE_PARM_DESC(pf_q_num, "Number of queues in PF(v1 0-4096, v2 0-1024)"); @@ -838,6 +881,8 @@ static int hisi_sec_probe(struct pci_dev *pdev, const struct pci_device_id *id) hisi_sec_add_to_list(hisi_sec); + hisi_sec->hisi_sec_list_lock = &hisi_sec_list_lock; + hisi_sec->sgl_pool = acc_create_sgl_pool(&pdev->dev, "hsec-sgl"); if (!hisi_sec->sgl_pool) return -ENOMEM; -- GitLab