From: Jun Yang <[email protected]> Release resources on probe failure and on uninit, and allocate the FQID range for a queue pair with a single ioctl instead of one per FQID to cut boot and quit time.
Export qman_release_fqid_range() from the bus, which dpaa_sec_uninit() needs to return the queue FQIDs in ranges. qman_shutdown_fq() falls back to get_affine_portal() when fq->qp is NULL, so affine a portal first in dpaa_sec_uninit() as probe does; rte_dev_remove() can run on a thread that never did. Release an FQID only once its queue actually shut down, in both uninit and the probe error paths: one that did not is still live in QMan, and handing its FQID back would let qman_alloc_fqid() give it to another user. Signed-off-by: Jun Yang <[email protected]> --- drivers/bus/dpaa/dpaa_bus_base_symbols.c | 1 + drivers/bus/dpaa/include/fsl_qman.h | 1 + drivers/crypto/dpaa_sec/dpaa_sec.c | 176 ++++++++++++++++++++--- 3 files changed, 160 insertions(+), 18 deletions(-) diff --git a/drivers/bus/dpaa/dpaa_bus_base_symbols.c b/drivers/bus/dpaa/dpaa_bus_base_symbols.c index 0927e5fe2c..aaa9f9bec2 100644 --- a/drivers/bus/dpaa/dpaa_bus_base_symbols.c +++ b/drivers/bus/dpaa/dpaa_bus_base_symbols.c @@ -52,6 +52,7 @@ RTE_EXPORT_INTERNAL_SYMBOL(bman_acquire) RTE_EXPORT_INTERNAL_SYMBOL(bman_query_free_buffers) RTE_EXPORT_INTERNAL_SYMBOL(bman_thread_irq) RTE_EXPORT_INTERNAL_SYMBOL(qman_alloc_fqid_range) +RTE_EXPORT_INTERNAL_SYMBOL(qman_release_fqid_range) RTE_EXPORT_INTERNAL_SYMBOL(qman_reserve_fqid_range) RTE_EXPORT_INTERNAL_SYMBOL(qman_alloc_pool_range) RTE_EXPORT_INTERNAL_SYMBOL(qman_alloc_cgrid_range) diff --git a/drivers/bus/dpaa/include/fsl_qman.h b/drivers/bus/dpaa/include/fsl_qman.h index 59b41e17f0..b2674ce5d0 100644 --- a/drivers/bus/dpaa/include/fsl_qman.h +++ b/drivers/bus/dpaa/include/fsl_qman.h @@ -1895,6 +1895,7 @@ static inline int qman_alloc_fqid(u32 *result) * This function can also be used to seed the allocator with ranges of FQIDs * that it can subsequently allocate from. */ +__rte_internal void qman_release_fqid_range(u32 fqid, unsigned int count); static inline void qman_release_fqid(u32 fqid) { diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c index c53ee70853..6972699c51 100644 --- a/drivers/crypto/dpaa_sec/dpaa_sec.c +++ b/drivers/crypto/dpaa_sec/dpaa_sec.c @@ -188,16 +188,15 @@ dqrr_out_fq_cb_rx(struct qman_portal *qm __always_unused, /* caam result is put into this queue */ static int -dpaa_sec_init_tx(struct qman_fq *fq) +dpaa_sec_init_tx(struct qman_fq *fq, uint32_t fqid) { int ret; struct qm_mcc_initfq opts; uint32_t flags; - flags = QMAN_FQ_FLAG_NO_ENQUEUE | QMAN_FQ_FLAG_LOCKED | - QMAN_FQ_FLAG_DYNAMIC_FQID; + flags = QMAN_FQ_FLAG_NO_ENQUEUE | QMAN_FQ_FLAG_LOCKED; - ret = qman_create_fq(0, flags, fq); + ret = qman_create_fq(fqid, flags, fq); if (unlikely(ret)) { DPAA_SEC_ERR("qman_create_fq failed"); return ret; @@ -3614,12 +3613,73 @@ static const struct rte_security_ops dpaa_sec_security_ops = { static int dpaa_sec_uninit(struct rte_cryptodev *dev) { - if (dev == NULL) + struct dpaa_sec_dev_private *internals; + uint32_t i, fqid, base, run; + int ret; + + if (!dev) return -ENODEV; + /* FQs and FQIDs are owned by the primary process. */ + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + + /* qman_shutdown_fq() needs an affine portal for fq->qp == NULL. */ + if (unlikely(!DPAA_PER_LCORE_PORTAL)) { + ret = rte_dpaa_portal_init((void *)0); + if (ret) { + DPAA_SEC_ERR("Failure in affining portal"); + return ret; + } + } + + internals = dev->data->dev_private; + /* Only release the FQID of a queue that actually shut down: one that + * did not is still live in QMan. Free in runs of adjacent FQIDs. + */ + base = 0; + run = 0; + for (i = 0; i < internals->max_nb_queue_pairs; i++) { + fqid = internals->qps[i].outq.fqid; + ret = qman_shutdown_fq(&internals->qps[i].outq); + if (ret) + DPAA_SEC_ERR("%s: Failed(%d) to shutdown TXQ(0x%08x), fqid not released", + dev->data->name, ret, fqid); + if (run && (ret || fqid != base + run)) { + qman_release_fqid_range(base, run); + run = 0; + } + if (ret || !fqid) + continue; + if (run++ == 0) + base = fqid; + } + if (run) + qman_release_fqid_range(base, run); + + base = 0; + run = 0; + for (i = 0; i < RTE_DPAA_MAX_RX_QUEUE; i++) { + fqid = internals->inq[i].fqid; + ret = qman_shutdown_fq(&internals->inq[i]); + if (ret) + DPAA_SEC_ERR("%s: Failed(%d) to shutdown RXQ[%d](0x%08x), fqid not released", + dev->data->name, ret, i, fqid); + if (run && (ret || fqid != base + run)) { + qman_release_fqid_range(base, run); + run = 0; + } + if (ret || !fqid) + continue; + if (run++ == 0) + base = fqid; + } + if (run) + qman_release_fqid_range(base, run); + rte_free(dev->security_ctx); DPAA_SEC_INFO("Closing DPAA_SEC device %s on numa socket %u", - dev->data->name, rte_socket_id()); + dev->data->name, rte_socket_id()); return 0; } @@ -3666,10 +3726,10 @@ dpaa_sec_dev_init(struct rte_cryptodev *cryptodev) struct dpaa_sec_dev_private *internals; struct rte_security_ctx *security_instance; struct dpaa_sec_qp *qp; - uint32_t i, flags; - int ret; + uint32_t i, j, flags, fqids[RTE_DPAA_MAX_RX_QUEUE]; + uint32_t fqid, base, run; + int ret, num = 0, map_fd = -1; void *cmd_map; - int map_fd = -1; PMD_INIT_FUNC_TRACE(); @@ -3735,24 +3795,47 @@ dpaa_sec_dev_init(struct rte_cryptodev *cryptodev) security_instance->sess_cnt = 0; cryptodev->security_ctx = security_instance; rte_spinlock_init(&internals->lock); + num = qman_alloc_fqid_range(fqids, internals->max_nb_queue_pairs, 0, 0); + if (num < (int)internals->max_nb_queue_pairs) { + if (num < 0) { + DPAA_SEC_ERR("%s: Failed(%d) to alloc %d TX fqids", + cryptodev->data->name, num, internals->max_nb_queue_pairs); + } else { + DPAA_SEC_ERR("%s: Alloc %d fqids < %d", + cryptodev->data->name, num, internals->max_nb_queue_pairs); + qman_release_fqid_range(fqids[0], num); + } + goto init_error; + } for (i = 0; i < internals->max_nb_queue_pairs; i++) { /* init qman fq for queue pair */ qp = &internals->qps[i]; - ret = dpaa_sec_init_tx(&qp->outq); + ret = dpaa_sec_init_tx(&qp->outq, fqids[i]); if (ret) { - DPAA_SEC_ERR("config tx of queue pair %d", i); - goto init_error; + DPAA_SEC_ERR("%s: Failed(%d) to init TXQ[%d](0x%08x)", + cryptodev->data->name, ret, i, fqids[i]); + goto init_error1; } } - flags = QMAN_FQ_FLAG_LOCKED | QMAN_FQ_FLAG_DYNAMIC_FQID | - QMAN_FQ_FLAG_TO_DCPORTAL; + flags = QMAN_FQ_FLAG_LOCKED | QMAN_FQ_FLAG_TO_DCPORTAL; + num = qman_alloc_fqid_range(fqids, RTE_DPAA_MAX_RX_QUEUE, 0, 0); + if (num < RTE_DPAA_MAX_RX_QUEUE) { + if (num < 0) { + DPAA_SEC_ERR("Failed(%d) to alloc %d fqids", num, RTE_DPAA_MAX_RX_QUEUE); + } else { + DPAA_SEC_ERR("Alloc %d fqids < %d", num, RTE_DPAA_MAX_RX_QUEUE); + qman_release_fqid_range(fqids[0], num); + } + goto init_error2; + } for (i = 0; i < RTE_DPAA_MAX_RX_QUEUE; i++) { /* create rx qman fq for sessions*/ - ret = qman_create_fq(0, flags, &internals->inq[i]); - if (unlikely(ret != 0)) { - DPAA_SEC_ERR("sec qman_create_fq failed"); - goto init_error; + ret = qman_create_fq(fqids[i], flags, &internals->inq[i]); + if (ret) { + DPAA_SEC_ERR("%s: Failed(%d) to create RXQ[%d](0x%08x)", + cryptodev->data->name, ret, i, fqids[i]); + goto init_error3; } } @@ -3761,6 +3844,63 @@ dpaa_sec_dev_init(struct rte_cryptodev *cryptodev) DPAA_SEC_INFO("%s cryptodev init", cryptodev->data->name); return 0; +init_error3: + /* Same rule as in uninit: do not release the FQID of a queue that + * failed to shut down. + */ + base = 0; + run = 0; + for (j = 0; j < i; j++) { + fqid = internals->inq[j].fqid; + ret = qman_shutdown_fq(&internals->inq[j]); + if (ret) { + DPAA_SEC_ERR("%s: Failed(%d) to shutdown RXQ(0x%08x), fqid not released", + cryptodev->data->name, ret, fqid); + } + if (run && (ret || fqid != base + run)) { + qman_release_fqid_range(base, run); + run = 0; + } + if (ret || !fqid) + continue; + if (run++ == 0) + base = fqid; + } + if (run) + qman_release_fqid_range(base, run); + /* FQIDs of the queues that were never created */ + if (i < RTE_DPAA_MAX_RX_QUEUE) + qman_release_fqid_range(fqids[i], RTE_DPAA_MAX_RX_QUEUE - i); +init_error2: + i = internals->max_nb_queue_pairs; + fqids[0] = internals->qps[0].outq.fqid; +init_error1: + base = 0; + run = 0; + for (j = 0; j < i; j++) { + qp = &internals->qps[j]; + fqid = qp->outq.fqid; + ret = qman_shutdown_fq(&qp->outq); + if (ret) { + DPAA_SEC_ERR("%s: Failed(%d) to shutdown TXQ(0x%08x), fqid not released", + cryptodev->data->name, ret, fqid); + } + if (run && (ret || fqid != base + run)) { + qman_release_fqid_range(base, run); + run = 0; + } + if (ret || !fqid) + continue; + if (run++ == 0) + base = fqid; + } + if (run) + qman_release_fqid_range(base, run); + /* FQIDs of the queues that were never created */ + if (i < internals->max_nb_queue_pairs) + qman_release_fqid_range(fqids[i], + internals->max_nb_queue_pairs - i); + init_error: DPAA_SEC_ERR("driver %s: create failed", cryptodev->data->name); -- 2.25.1

