Skip to content

Commit 18f1ab3

Browse files
tsk-lieacuiherbertx
authored andcommitted
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 <[email protected]> Reviewed-by: Zhou Wang <[email protected]> Reviewed-by: Zaibo Xu <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 3f1ec97 commit 18f1ab3

File tree

3 files changed

+34
-114
lines changed

3 files changed

+34
-114
lines changed

drivers/crypto/hisilicon/zip/zip.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ struct hisi_zip_sqe {
6868
u32 rsvd1[4];
6969
};
7070

71-
struct hisi_zip *find_zip_device(int node);
71+
int zip_create_qps(struct hisi_qp **qps, int ctx_num);
7272
int hisi_zip_register_to_crypto(void);
7373
void hisi_zip_unregister_from_crypto(void);
7474
#endif

drivers/crypto/hisilicon/zip/zip_crypto.c

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -132,29 +132,25 @@ static void hisi_zip_fill_sqe(struct hisi_zip_sqe *sqe, u8 req_type,
132132
sqe->dest_addr_h = upper_32_bits(d_addr);
133133
}
134134

135-
static int hisi_zip_create_qp(struct hisi_qm *qm, struct hisi_zip_qp_ctx *ctx,
136-
int alg_type, int req_type)
135+
static int hisi_zip_start_qp(struct hisi_qp *qp, struct hisi_zip_qp_ctx *ctx,
136+
int alg_type, int req_type)
137137
{
138-
struct hisi_qp *qp;
138+
struct device *dev = &qp->qm->pdev->dev;
139139
int ret;
140140

141-
qp = hisi_qm_create_qp(qm, alg_type);
142-
if (IS_ERR(qp))
143-
return PTR_ERR(qp);
144-
145141
qp->req_type = req_type;
142+
qp->alg_type = alg_type;
146143
qp->qp_ctx = ctx;
147-
ctx->qp = qp;
148144

149145
ret = hisi_qm_start_qp(qp, 0);
150-
if (ret < 0)
151-
goto err_release_qp;
146+
if (ret < 0) {
147+
dev_err(dev, "start qp failed!\n");
148+
return ret;
149+
}
152150

153-
return 0;
151+
ctx->qp = qp;
154152

155-
err_release_qp:
156-
hisi_qm_release_qp(qp);
157-
return ret;
153+
return 0;
158154
}
159155

160156
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)
165161

166162
static int hisi_zip_ctx_init(struct hisi_zip_ctx *hisi_zip_ctx, u8 req_type)
167163
{
164+
struct hisi_qp *qps[HZIP_CTX_Q_NUM] = { NULL };
168165
struct hisi_zip *hisi_zip;
169-
struct hisi_qm *qm;
170166
int ret, i, j;
171167

172-
/* find the proper zip device */
173-
hisi_zip = find_zip_device(cpu_to_node(smp_processor_id()));
174-
if (!hisi_zip) {
175-
pr_err("Failed to find a proper ZIP device!\n");
168+
ret = zip_create_qps(qps, HZIP_CTX_Q_NUM);
169+
if (ret) {
170+
pr_err("Can not create zip qps!\n");
176171
return -ENODEV;
177172
}
178-
qm = &hisi_zip->qm;
173+
174+
hisi_zip = container_of(qps[0]->qm, struct hisi_zip, qm);
179175

180176
for (i = 0; i < HZIP_CTX_Q_NUM; i++) {
181177
/* alg_type = 0 for compress, 1 for decompress in hw sqe */
182-
ret = hisi_zip_create_qp(qm, &hisi_zip_ctx->qp_ctx[i], i,
183-
req_type);
184-
if (ret)
185-
goto err;
178+
ret = hisi_zip_start_qp(qps[i], &hisi_zip_ctx->qp_ctx[i], i,
179+
req_type);
180+
if (ret) {
181+
for (j = i - 1; j >= 0; j--)
182+
hisi_qm_stop_qp(hisi_zip_ctx->qp_ctx[j].qp);
183+
184+
hisi_qm_free_qps(qps, HZIP_CTX_Q_NUM);
185+
return ret;
186+
}
186187

187188
hisi_zip_ctx->qp_ctx[i].zip_dev = hisi_zip;
188189
}
189190

190191
return 0;
191-
err:
192-
for (j = i - 1; j >= 0; j--)
193-
hisi_zip_release_qp(&hisi_zip_ctx->qp_ctx[j]);
194-
195-
return ret;
196192
}
197193

198194
static void hisi_zip_ctx_exit(struct hisi_zip_ctx *hisi_zip_ctx)

drivers/crypto/hisilicon/zip/zip_main.c

Lines changed: 8 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -88,77 +88,7 @@
8888

8989
static const char hisi_zip_name[] = "hisi_zip";
9090
static struct dentry *hzip_debugfs_root;
91-
static LIST_HEAD(hisi_zip_list);
92-
static DEFINE_MUTEX(hisi_zip_list_lock);
93-
94-
struct hisi_zip_resource {
95-
struct hisi_zip *hzip;
96-
int distance;
97-
struct list_head list;
98-
};
99-
100-
static void free_list(struct list_head *head)
101-
{
102-
struct hisi_zip_resource *res, *tmp;
103-
104-
list_for_each_entry_safe(res, tmp, head, list) {
105-
list_del(&res->list);
106-
kfree(res);
107-
}
108-
}
109-
110-
struct hisi_zip *find_zip_device(int node)
111-
{
112-
struct hisi_zip_resource *res, *tmp;
113-
struct hisi_zip *ret = NULL;
114-
struct hisi_zip *hisi_zip;
115-
struct list_head *n;
116-
struct device *dev;
117-
LIST_HEAD(head);
118-
119-
mutex_lock(&hisi_zip_list_lock);
120-
121-
if (IS_ENABLED(CONFIG_NUMA)) {
122-
list_for_each_entry(hisi_zip, &hisi_zip_list, list) {
123-
res = kzalloc(sizeof(*res), GFP_KERNEL);
124-
if (!res)
125-
goto err;
126-
127-
dev = &hisi_zip->qm.pdev->dev;
128-
res->hzip = hisi_zip;
129-
res->distance = node_distance(dev_to_node(dev), node);
130-
131-
n = &head;
132-
list_for_each_entry(tmp, &head, list) {
133-
if (res->distance < tmp->distance) {
134-
n = &tmp->list;
135-
break;
136-
}
137-
}
138-
list_add_tail(&res->list, n);
139-
}
140-
141-
list_for_each_entry(tmp, &head, list) {
142-
if (hisi_qm_get_free_qp_num(&tmp->hzip->qm)) {
143-
ret = tmp->hzip;
144-
break;
145-
}
146-
}
147-
148-
free_list(&head);
149-
} else {
150-
ret = list_first_entry(&hisi_zip_list, struct hisi_zip, list);
151-
}
152-
153-
mutex_unlock(&hisi_zip_list_lock);
154-
155-
return ret;
156-
157-
err:
158-
free_list(&head);
159-
mutex_unlock(&hisi_zip_list_lock);
160-
return NULL;
161-
}
91+
static struct hisi_qm_list zip_devices;
16292

16393
struct hisi_zip_hw_error {
16494
u32 int_msk;
@@ -313,18 +243,11 @@ static const struct pci_device_id hisi_zip_dev_ids[] = {
313243
};
314244
MODULE_DEVICE_TABLE(pci, hisi_zip_dev_ids);
315245

316-
static inline void hisi_zip_add_to_list(struct hisi_zip *hisi_zip)
246+
int zip_create_qps(struct hisi_qp **qps, int qp_num)
317247
{
318-
mutex_lock(&hisi_zip_list_lock);
319-
list_add_tail(&hisi_zip->list, &hisi_zip_list);
320-
mutex_unlock(&hisi_zip_list_lock);
321-
}
248+
int node = cpu_to_node(smp_processor_id());
322249

323-
static inline void hisi_zip_remove_from_list(struct hisi_zip *hisi_zip)
324-
{
325-
mutex_lock(&hisi_zip_list_lock);
326-
list_del(&hisi_zip->list);
327-
mutex_unlock(&hisi_zip_list_lock);
250+
return hisi_qm_alloc_qps_node(&zip_devices, qp_num, 0, node, qps);
328251
}
329252

330253
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)
891814
if (ret)
892815
dev_err(&pdev->dev, "Failed to init debugfs (%d)!\n", ret);
893816

894-
hisi_zip_add_to_list(hisi_zip);
817+
hisi_qm_add_to_list(qm, &zip_devices);
895818

896819
if (qm->uacce) {
897820
ret = uacce_register(qm->uacce);
@@ -908,7 +831,7 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
908831
return 0;
909832

910833
err_remove_from_list:
911-
hisi_zip_remove_from_list(hisi_zip);
834+
hisi_qm_del_from_list(qm, &zip_devices);
912835
hisi_zip_debugfs_exit(hisi_zip);
913836
hisi_qm_stop(qm);
914837
err_qm_uninit:
@@ -937,7 +860,7 @@ static void hisi_zip_remove(struct pci_dev *pdev)
937860

938861
hisi_qm_dev_err_uninit(qm);
939862
hisi_qm_uninit(qm);
940-
hisi_zip_remove_from_list(hisi_zip);
863+
hisi_qm_del_from_list(qm, &zip_devices);
941864
}
942865

943866
static const struct pci_error_handlers hisi_zip_err_handler = {
@@ -971,6 +894,7 @@ static int __init hisi_zip_init(void)
971894
{
972895
int ret;
973896

897+
hisi_qm_init_list(&zip_devices);
974898
hisi_zip_register_debugfs();
975899

976900
ret = pci_register_driver(&hisi_zip_pci_driver);

0 commit comments

Comments
 (0)