crypto: hisilicon/zip - Use hisi_qm_alloc_qps_node() when init ctx

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>
This commit is contained in:
Shukun Tan 2020-03-10 16:42:50 +08:00 committed by Herbert Xu
parent 3f1ec97aac
commit 18f1ab3f74
3 changed files with 34 additions and 114 deletions

View 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

View 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;
}
ctx->qp = qp;
return 0;
err_release_qp:
hisi_qm_release_qp(qp);
return ret;
}
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)

View File

@ -88,77 +88,7 @@
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);