Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: hisilicon/qm - centralize the sending locks of each module into qm

When a single queue used by multiple tfms, the protection of shared
resources by individual module driver programs is no longer
sufficient. The hisi_qp_send needs to be ensured by the lock in qp.

Fixes: 5fdb4b345cfb ("crypto: hisilicon - add a lock for the qp send operation")
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>

authored by

Chenghai Huang and committed by
Herbert Xu
8cd9b608 21452eaa

+13 -11
-4
drivers/crypto/hisilicon/hpre/hpre_crypto.c
··· 109 109 struct hisi_qp *qp; 110 110 struct device *dev; 111 111 struct hpre *hpre; 112 - spinlock_t req_lock; 113 112 unsigned int key_sz; 114 113 bool crt_g2_mode; 115 114 union { ··· 409 410 410 411 qp->qp_ctx = ctx; 411 412 qp->req_cb = hpre_alg_cb; 412 - spin_lock_init(&ctx->req_lock); 413 413 ctx->qp = qp; 414 414 ctx->dev = &qp->qm->pdev->dev; 415 415 hpre = container_of(ctx->qp->qm, struct hpre, qm); ··· 476 478 477 479 do { 478 480 atomic64_inc(&dfx[HPRE_SEND_CNT].value); 479 - spin_lock_bh(&ctx->req_lock); 480 481 ret = hisi_qp_send(ctx->qp, msg); 481 - spin_unlock_bh(&ctx->req_lock); 482 482 if (ret != -EBUSY) 483 483 break; 484 484 atomic64_inc(&dfx[HPRE_SEND_BUSY_CNT].value);
+12 -4
drivers/crypto/hisilicon/qm.c
··· 2369 2369 int hisi_qp_send(struct hisi_qp *qp, const void *msg) 2370 2370 { 2371 2371 struct hisi_qp_status *qp_status = &qp->qp_status; 2372 - u16 sq_tail = qp_status->sq_tail; 2373 - u16 sq_tail_next = (sq_tail + 1) % qp->sq_depth; 2374 - void *sqe = qm_get_avail_sqe(qp); 2372 + u16 sq_tail, sq_tail_next; 2373 + void *sqe; 2375 2374 2375 + spin_lock_bh(&qp->qp_lock); 2376 2376 if (unlikely(atomic_read(&qp->qp_status.flags) == QP_STOP || 2377 2377 atomic_read(&qp->qm->status.flags) == QM_STOP || 2378 2378 qp->is_resetting)) { 2379 + spin_unlock_bh(&qp->qp_lock); 2379 2380 dev_info_ratelimited(&qp->qm->pdev->dev, "QP is stopped or resetting\n"); 2380 2381 return -EAGAIN; 2381 2382 } 2382 2383 2383 - if (!sqe) 2384 + sqe = qm_get_avail_sqe(qp); 2385 + if (!sqe) { 2386 + spin_unlock_bh(&qp->qp_lock); 2384 2387 return -EBUSY; 2388 + } 2385 2389 2390 + sq_tail = qp_status->sq_tail; 2391 + sq_tail_next = (sq_tail + 1) % qp->sq_depth; 2386 2392 memcpy(sqe, msg, qp->qm->sqe_size); 2387 2393 qp->msg[sq_tail] = msg; 2388 2394 2389 2395 qm_db(qp->qm, qp->qp_id, QM_DOORBELL_CMD_SQ, sq_tail_next, 0); 2390 2396 atomic_inc(&qp->qp_status.used); 2391 2397 qp_status->sq_tail = sq_tail_next; 2398 + spin_unlock_bh(&qp->qp_lock); 2392 2399 2393 2400 return 0; 2394 2401 } ··· 2975 2968 qp->qm = qm; 2976 2969 qp->qp_id = id; 2977 2970 2971 + spin_lock_init(&qp->qp_lock); 2978 2972 spin_lock_init(&qp->backlog.lock); 2979 2973 INIT_LIST_HEAD(&qp->backlog.list); 2980 2974
-3
drivers/crypto/hisilicon/zip/zip_crypto.c
··· 217 217 { 218 218 struct hisi_acc_sgl_pool *pool = qp_ctx->sgl_pool; 219 219 struct hisi_zip_dfx *dfx = &qp_ctx->zip_dev->dfx; 220 - struct hisi_zip_req_q *req_q = &qp_ctx->req_q; 221 220 struct acomp_req *a_req = req->req; 222 221 struct hisi_qp *qp = qp_ctx->qp; 223 222 struct device *dev = &qp->qm->pdev->dev; ··· 249 250 250 251 /* send command to start a task */ 251 252 atomic64_inc(&dfx->send_cnt); 252 - spin_lock_bh(&req_q->req_lock); 253 253 ret = hisi_qp_send(qp, &zip_sqe); 254 - spin_unlock_bh(&req_q->req_lock); 255 254 if (unlikely(ret < 0)) { 256 255 atomic64_inc(&dfx->send_busy_cnt); 257 256 ret = -EAGAIN;
+1
include/linux/hisi_acc_qm.h
··· 476 476 u16 pasid; 477 477 struct uacce_queue *uacce_q; 478 478 479 + spinlock_t qp_lock; 479 480 struct instance_backlog backlog; 480 481 const void **msg; 481 482 };