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

crypto: caam/qi - optimize frame queue cleanup

Add reference counter incremented for each frame enqueued in CAAM
and replace unconditional sleep in empty_caam_fq() with polling the
reference counter.

When CONFIG_CRYPTO_MANAGER_EXTRA_TESTS=y boot time on LS1043A
platform with this optimization decreases from ~1100s to ~11s.

Signed-off-by: Valentin Ciocoi Radulescu <valentin.ciocoi@nxp.com>
Reviewed-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Valentin Ciocoi Radulescu and committed by
Herbert Xu
11144416 21f802cc

+42 -22
+39 -21
drivers/crypto/caam/qi.c
··· 4 4 * Queue Interface backend functionality 5 5 * 6 6 * Copyright 2013-2016 Freescale Semiconductor, Inc. 7 - * Copyright 2016-2017, 2019 NXP 7 + * Copyright 2016-2017, 2019-2020 NXP 8 8 */ 9 9 10 10 #include <linux/cpumask.h> ··· 124 124 125 125 do { 126 126 ret = qman_enqueue(req->drv_ctx->req_fq, &fd); 127 - if (likely(!ret)) 127 + if (likely(!ret)) { 128 + refcount_inc(&req->drv_ctx->refcnt); 128 129 return 0; 130 + } 129 131 130 132 if (ret != -EBUSY) 131 133 break; ··· 150 148 151 149 fd = &msg->ern.fd; 152 150 153 - if (qm_fd_get_format(fd) != qm_fd_compound) { 154 - dev_err(qidev, "Non-compound FD from CAAM\n"); 155 - return; 156 - } 157 - 158 151 drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd)); 159 152 if (!drv_req) { 160 153 dev_err(qidev, 161 154 "Can't find original request for CAAM response\n"); 155 + return; 156 + } 157 + 158 + refcount_dec(&drv_req->drv_ctx->refcnt); 159 + 160 + if (qm_fd_get_format(fd) != qm_fd_compound) { 161 + dev_err(qidev, "Non-compound FD from CAAM\n"); 162 162 return; 163 163 } 164 164 ··· 291 287 return ret; 292 288 } 293 289 294 - static int empty_caam_fq(struct qman_fq *fq) 290 + static int empty_caam_fq(struct qman_fq *fq, struct caam_drv_ctx *drv_ctx) 295 291 { 296 292 int ret; 293 + int retries = 10; 297 294 struct qm_mcr_queryfq_np np; 298 295 299 296 /* Wait till the older CAAM FQ get empty */ ··· 309 304 msleep(20); 310 305 } while (1); 311 306 312 - /* 313 - * Give extra time for pending jobs from this FQ in holding tanks 314 - * to get processed 315 - */ 316 - msleep(20); 307 + /* Wait until pending jobs from this FQ are processed by CAAM */ 308 + do { 309 + if (refcount_read(&drv_ctx->refcnt) == 1) 310 + break; 311 + 312 + msleep(20); 313 + } while (--retries); 314 + 315 + if (!retries) 316 + dev_warn_once(drv_ctx->qidev, "%d frames from FQID %u still pending in CAAM\n", 317 + refcount_read(&drv_ctx->refcnt), fq->fqid); 318 + 317 319 return 0; 318 320 } 319 321 ··· 352 340 drv_ctx->req_fq = new_fq; 353 341 354 342 /* Empty and remove the older FQ */ 355 - ret = empty_caam_fq(old_fq); 343 + ret = empty_caam_fq(old_fq, drv_ctx); 356 344 if (ret) { 357 345 dev_err(qidev, "Old CAAM FQ empty failed: %d\n", ret); 358 346 ··· 464 452 kfree(drv_ctx); 465 453 return ERR_PTR(-ENOMEM); 466 454 } 455 + 456 + /* init reference counter used to track references to request FQ */ 457 + refcount_set(&drv_ctx->refcnt, 1); 467 458 468 459 drv_ctx->qidev = qidev; 469 460 return drv_ctx; ··· 586 571 return qman_cb_dqrr_stop; 587 572 588 573 fd = &dqrr->fd; 574 + 575 + drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd)); 576 + if (unlikely(!drv_req)) { 577 + dev_err(qidev, 578 + "Can't find original request for caam response\n"); 579 + return qman_cb_dqrr_consume; 580 + } 581 + 582 + refcount_dec(&drv_req->drv_ctx->refcnt); 583 + 589 584 status = be32_to_cpu(fd->status); 590 585 if (unlikely(status)) { 591 586 u32 ssrc = status & JRSTA_SSRC_MASK; ··· 610 585 611 586 if (unlikely(qm_fd_get_format(fd) != qm_fd_compound)) { 612 587 dev_err(qidev, "Non-compound FD from CAAM\n"); 613 - return qman_cb_dqrr_consume; 614 - } 615 - 616 - drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd)); 617 - if (unlikely(!drv_req)) { 618 - dev_err(qidev, 619 - "Can't find original request for caam response\n"); 620 588 return qman_cb_dqrr_consume; 621 589 } 622 590
+3 -1
drivers/crypto/caam/qi.h
··· 3 3 * Public definitions for the CAAM/QI (Queue Interface) backend. 4 4 * 5 5 * Copyright 2013-2016 Freescale Semiconductor, Inc. 6 - * Copyright 2016-2017 NXP 6 + * Copyright 2016-2017, 2020 NXP 7 7 */ 8 8 9 9 #ifndef __QI_H__ ··· 52 52 * @context_a: shared descriptor dma address 53 53 * @req_fq: to-CAAM request frame queue 54 54 * @rsp_fq: from-CAAM response frame queue 55 + * @refcnt: reference counter incremented for each frame enqueued in to-CAAM FQ 55 56 * @cpu: cpu on which to receive CAAM response 56 57 * @op_type: operation type 57 58 * @qidev: device pointer for CAAM/QI backend ··· 63 62 dma_addr_t context_a; 64 63 struct qman_fq *req_fq; 65 64 struct qman_fq *rsp_fq; 65 + refcount_t refcnt; 66 66 int cpu; 67 67 enum optype op_type; 68 68 struct device *qidev;