Commit 11144416 authored by Valentin Ciocoi Radulescu's avatar Valentin Ciocoi Radulescu Committed by Herbert Xu

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: default avatarValentin Ciocoi Radulescu <valentin.ciocoi@nxp.com>
Reviewed-by: default avatarHoria Geantă <horia.geanta@nxp.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 21f802cc
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Queue Interface backend functionality * Queue Interface backend functionality
* *
* Copyright 2013-2016 Freescale Semiconductor, Inc. * Copyright 2013-2016 Freescale Semiconductor, Inc.
* Copyright 2016-2017, 2019 NXP * Copyright 2016-2017, 2019-2020 NXP
*/ */
#include <linux/cpumask.h> #include <linux/cpumask.h>
...@@ -124,8 +124,10 @@ int caam_qi_enqueue(struct device *qidev, struct caam_drv_req *req) ...@@ -124,8 +124,10 @@ int caam_qi_enqueue(struct device *qidev, struct caam_drv_req *req)
do { do {
ret = qman_enqueue(req->drv_ctx->req_fq, &fd); ret = qman_enqueue(req->drv_ctx->req_fq, &fd);
if (likely(!ret)) if (likely(!ret)) {
refcount_inc(&req->drv_ctx->refcnt);
return 0; return 0;
}
if (ret != -EBUSY) if (ret != -EBUSY)
break; break;
...@@ -148,11 +150,6 @@ static void caam_fq_ern_cb(struct qman_portal *qm, struct qman_fq *fq, ...@@ -148,11 +150,6 @@ static void caam_fq_ern_cb(struct qman_portal *qm, struct qman_fq *fq,
fd = &msg->ern.fd; fd = &msg->ern.fd;
if (qm_fd_get_format(fd) != qm_fd_compound) {
dev_err(qidev, "Non-compound FD from CAAM\n");
return;
}
drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd)); drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd));
if (!drv_req) { if (!drv_req) {
dev_err(qidev, dev_err(qidev,
...@@ -160,6 +157,13 @@ static void caam_fq_ern_cb(struct qman_portal *qm, struct qman_fq *fq, ...@@ -160,6 +157,13 @@ static void caam_fq_ern_cb(struct qman_portal *qm, struct qman_fq *fq,
return; return;
} }
refcount_dec(&drv_req->drv_ctx->refcnt);
if (qm_fd_get_format(fd) != qm_fd_compound) {
dev_err(qidev, "Non-compound FD from CAAM\n");
return;
}
dma_unmap_single(drv_req->drv_ctx->qidev, qm_fd_addr(fd), dma_unmap_single(drv_req->drv_ctx->qidev, qm_fd_addr(fd),
sizeof(drv_req->fd_sgt), DMA_BIDIRECTIONAL); sizeof(drv_req->fd_sgt), DMA_BIDIRECTIONAL);
...@@ -287,9 +291,10 @@ static int kill_fq(struct device *qidev, struct qman_fq *fq) ...@@ -287,9 +291,10 @@ static int kill_fq(struct device *qidev, struct qman_fq *fq)
return ret; return ret;
} }
static int empty_caam_fq(struct qman_fq *fq) static int empty_caam_fq(struct qman_fq *fq, struct caam_drv_ctx *drv_ctx)
{ {
int ret; int ret;
int retries = 10;
struct qm_mcr_queryfq_np np; struct qm_mcr_queryfq_np np;
/* Wait till the older CAAM FQ get empty */ /* Wait till the older CAAM FQ get empty */
...@@ -304,11 +309,18 @@ static int empty_caam_fq(struct qman_fq *fq) ...@@ -304,11 +309,18 @@ static int empty_caam_fq(struct qman_fq *fq)
msleep(20); msleep(20);
} while (1); } while (1);
/* /* Wait until pending jobs from this FQ are processed by CAAM */
* Give extra time for pending jobs from this FQ in holding tanks do {
* to get processed if (refcount_read(&drv_ctx->refcnt) == 1)
*/ break;
msleep(20);
msleep(20);
} while (--retries);
if (!retries)
dev_warn_once(drv_ctx->qidev, "%d frames from FQID %u still pending in CAAM\n",
refcount_read(&drv_ctx->refcnt), fq->fqid);
return 0; return 0;
} }
...@@ -340,7 +352,7 @@ int caam_drv_ctx_update(struct caam_drv_ctx *drv_ctx, u32 *sh_desc) ...@@ -340,7 +352,7 @@ int caam_drv_ctx_update(struct caam_drv_ctx *drv_ctx, u32 *sh_desc)
drv_ctx->req_fq = new_fq; drv_ctx->req_fq = new_fq;
/* Empty and remove the older FQ */ /* Empty and remove the older FQ */
ret = empty_caam_fq(old_fq); ret = empty_caam_fq(old_fq, drv_ctx);
if (ret) { if (ret) {
dev_err(qidev, "Old CAAM FQ empty failed: %d\n", ret); dev_err(qidev, "Old CAAM FQ empty failed: %d\n", ret);
...@@ -453,6 +465,9 @@ struct caam_drv_ctx *caam_drv_ctx_init(struct device *qidev, ...@@ -453,6 +465,9 @@ struct caam_drv_ctx *caam_drv_ctx_init(struct device *qidev,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
/* init reference counter used to track references to request FQ */
refcount_set(&drv_ctx->refcnt, 1);
drv_ctx->qidev = qidev; drv_ctx->qidev = qidev;
return drv_ctx; return drv_ctx;
} }
...@@ -571,6 +586,16 @@ static enum qman_cb_dqrr_result caam_rsp_fq_dqrr_cb(struct qman_portal *p, ...@@ -571,6 +586,16 @@ static enum qman_cb_dqrr_result caam_rsp_fq_dqrr_cb(struct qman_portal *p,
return qman_cb_dqrr_stop; return qman_cb_dqrr_stop;
fd = &dqrr->fd; fd = &dqrr->fd;
drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd));
if (unlikely(!drv_req)) {
dev_err(qidev,
"Can't find original request for caam response\n");
return qman_cb_dqrr_consume;
}
refcount_dec(&drv_req->drv_ctx->refcnt);
status = be32_to_cpu(fd->status); status = be32_to_cpu(fd->status);
if (unlikely(status)) { if (unlikely(status)) {
u32 ssrc = status & JRSTA_SSRC_MASK; 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, ...@@ -588,13 +613,6 @@ static enum qman_cb_dqrr_result caam_rsp_fq_dqrr_cb(struct qman_portal *p,
return qman_cb_dqrr_consume; return qman_cb_dqrr_consume;
} }
drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd));
if (unlikely(!drv_req)) {
dev_err(qidev,
"Can't find original request for caam response\n");
return qman_cb_dqrr_consume;
}
dma_unmap_single(drv_req->drv_ctx->qidev, qm_fd_addr(fd), dma_unmap_single(drv_req->drv_ctx->qidev, qm_fd_addr(fd),
sizeof(drv_req->fd_sgt), DMA_BIDIRECTIONAL); sizeof(drv_req->fd_sgt), DMA_BIDIRECTIONAL);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Public definitions for the CAAM/QI (Queue Interface) backend. * Public definitions for the CAAM/QI (Queue Interface) backend.
* *
* Copyright 2013-2016 Freescale Semiconductor, Inc. * Copyright 2013-2016 Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP * Copyright 2016-2017, 2020 NXP
*/ */
#ifndef __QI_H__ #ifndef __QI_H__
...@@ -52,6 +52,7 @@ enum optype { ...@@ -52,6 +52,7 @@ enum optype {
* @context_a: shared descriptor dma address * @context_a: shared descriptor dma address
* @req_fq: to-CAAM request frame queue * @req_fq: to-CAAM request frame queue
* @rsp_fq: from-CAAM response frame queue * @rsp_fq: from-CAAM response frame queue
* @refcnt: reference counter incremented for each frame enqueued in to-CAAM FQ
* @cpu: cpu on which to receive CAAM response * @cpu: cpu on which to receive CAAM response
* @op_type: operation type * @op_type: operation type
* @qidev: device pointer for CAAM/QI backend * @qidev: device pointer for CAAM/QI backend
...@@ -62,6 +63,7 @@ struct caam_drv_ctx { ...@@ -62,6 +63,7 @@ struct caam_drv_ctx {
dma_addr_t context_a; dma_addr_t context_a;
struct qman_fq *req_fq; struct qman_fq *req_fq;
struct qman_fq *rsp_fq; struct qman_fq *rsp_fq;
refcount_t refcnt;
int cpu; int cpu;
enum optype op_type; enum optype op_type;
struct device *qidev; struct device *qidev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment