Skip to content

Commit 1114441

Browse files
Valentin Ciocoi Radulescuherbertx
authored andcommitted
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 <[email protected]> Reviewed-by: Horia Geantă <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 21f802c commit 1114441

File tree

2 files changed

+42
-22
lines changed

2 files changed

+42
-22
lines changed

drivers/crypto/caam/qi.c

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Queue Interface backend functionality
55
*
66
* Copyright 2013-2016 Freescale Semiconductor, Inc.
7-
* Copyright 2016-2017, 2019 NXP
7+
* Copyright 2016-2017, 2019-2020 NXP
88
*/
99

1010
#include <linux/cpumask.h>
@@ -124,8 +124,10 @@ int caam_qi_enqueue(struct device *qidev, struct caam_drv_req *req)
124124

125125
do {
126126
ret = qman_enqueue(req->drv_ctx->req_fq, &fd);
127-
if (likely(!ret))
127+
if (likely(!ret)) {
128+
refcount_inc(&req->drv_ctx->refcnt);
128129
return 0;
130+
}
129131

130132
if (ret != -EBUSY)
131133
break;
@@ -148,18 +150,20 @@ static void caam_fq_ern_cb(struct qman_portal *qm, struct qman_fq *fq,
148150

149151
fd = &msg->ern.fd;
150152

151-
if (qm_fd_get_format(fd) != qm_fd_compound) {
152-
dev_err(qidev, "Non-compound FD from CAAM\n");
153-
return;
154-
}
155-
156153
drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd));
157154
if (!drv_req) {
158155
dev_err(qidev,
159156
"Can't find original request for CAAM response\n");
160157
return;
161158
}
162159

160+
refcount_dec(&drv_req->drv_ctx->refcnt);
161+
162+
if (qm_fd_get_format(fd) != qm_fd_compound) {
163+
dev_err(qidev, "Non-compound FD from CAAM\n");
164+
return;
165+
}
166+
163167
dma_unmap_single(drv_req->drv_ctx->qidev, qm_fd_addr(fd),
164168
sizeof(drv_req->fd_sgt), DMA_BIDIRECTIONAL);
165169

@@ -287,9 +291,10 @@ static int kill_fq(struct device *qidev, struct qman_fq *fq)
287291
return ret;
288292
}
289293

290-
static int empty_caam_fq(struct qman_fq *fq)
294+
static int empty_caam_fq(struct qman_fq *fq, struct caam_drv_ctx *drv_ctx)
291295
{
292296
int ret;
297+
int retries = 10;
293298
struct qm_mcr_queryfq_np np;
294299

295300
/* Wait till the older CAAM FQ get empty */
@@ -304,11 +309,18 @@ static int empty_caam_fq(struct qman_fq *fq)
304309
msleep(20);
305310
} while (1);
306311

307-
/*
308-
* Give extra time for pending jobs from this FQ in holding tanks
309-
* to get processed
310-
*/
311-
msleep(20);
312+
/* Wait until pending jobs from this FQ are processed by CAAM */
313+
do {
314+
if (refcount_read(&drv_ctx->refcnt) == 1)
315+
break;
316+
317+
msleep(20);
318+
} while (--retries);
319+
320+
if (!retries)
321+
dev_warn_once(drv_ctx->qidev, "%d frames from FQID %u still pending in CAAM\n",
322+
refcount_read(&drv_ctx->refcnt), fq->fqid);
323+
312324
return 0;
313325
}
314326

@@ -340,7 +352,7 @@ int caam_drv_ctx_update(struct caam_drv_ctx *drv_ctx, u32 *sh_desc)
340352
drv_ctx->req_fq = new_fq;
341353

342354
/* Empty and remove the older FQ */
343-
ret = empty_caam_fq(old_fq);
355+
ret = empty_caam_fq(old_fq, drv_ctx);
344356
if (ret) {
345357
dev_err(qidev, "Old CAAM FQ empty failed: %d\n", ret);
346358

@@ -453,6 +465,9 @@ struct caam_drv_ctx *caam_drv_ctx_init(struct device *qidev,
453465
return ERR_PTR(-ENOMEM);
454466
}
455467

468+
/* init reference counter used to track references to request FQ */
469+
refcount_set(&drv_ctx->refcnt, 1);
470+
456471
drv_ctx->qidev = qidev;
457472
return drv_ctx;
458473
}
@@ -571,6 +586,16 @@ static enum qman_cb_dqrr_result caam_rsp_fq_dqrr_cb(struct qman_portal *p,
571586
return qman_cb_dqrr_stop;
572587

573588
fd = &dqrr->fd;
589+
590+
drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd));
591+
if (unlikely(!drv_req)) {
592+
dev_err(qidev,
593+
"Can't find original request for caam response\n");
594+
return qman_cb_dqrr_consume;
595+
}
596+
597+
refcount_dec(&drv_req->drv_ctx->refcnt);
598+
574599
status = be32_to_cpu(fd->status);
575600
if (unlikely(status)) {
576601
u32 ssrc = status & JRSTA_SSRC_MASK;
@@ -588,13 +613,6 @@ static enum qman_cb_dqrr_result caam_rsp_fq_dqrr_cb(struct qman_portal *p,
588613
return qman_cb_dqrr_consume;
589614
}
590615

591-
drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd));
592-
if (unlikely(!drv_req)) {
593-
dev_err(qidev,
594-
"Can't find original request for caam response\n");
595-
return qman_cb_dqrr_consume;
596-
}
597-
598616
dma_unmap_single(drv_req->drv_ctx->qidev, qm_fd_addr(fd),
599617
sizeof(drv_req->fd_sgt), DMA_BIDIRECTIONAL);
600618

drivers/crypto/caam/qi.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Public definitions for the CAAM/QI (Queue Interface) backend.
44
*
55
* Copyright 2013-2016 Freescale Semiconductor, Inc.
6-
* Copyright 2016-2017 NXP
6+
* Copyright 2016-2017, 2020 NXP
77
*/
88

99
#ifndef __QI_H__
@@ -52,6 +52,7 @@ enum optype {
5252
* @context_a: shared descriptor dma address
5353
* @req_fq: to-CAAM request frame queue
5454
* @rsp_fq: from-CAAM response frame queue
55+
* @refcnt: reference counter incremented for each frame enqueued in to-CAAM FQ
5556
* @cpu: cpu on which to receive CAAM response
5657
* @op_type: operation type
5758
* @qidev: device pointer for CAAM/QI backend
@@ -62,6 +63,7 @@ struct caam_drv_ctx {
6263
dma_addr_t context_a;
6364
struct qman_fq *req_fq;
6465
struct qman_fq *rsp_fq;
66+
refcount_t refcnt;
6567
int cpu;
6668
enum optype op_type;
6769
struct device *qidev;

0 commit comments

Comments
 (0)