NPA_POOL_ERR_INT_RANGE fires spuriously between pool creation
(ptr_start/ptr_end default to 0/~0) and the actual range install
via roc_npa_pool_op_range_set(). On CN10K this drains the pool
stack and makes the pool unusable.
Fix by masking NPA_POOL_ERR_INT_RANGE at pool creation time, then
re-enabling it (along with OVFLS and PERR) after the valid range
is installed. Add roc_npa_pool_range_int_enable() for this and
call it from both cnxk_mempool_populate() (regular mempools) and
sqb_pool_populate() (NIX SQ buffer pools).
Fixes: f765f5611240 ("common/cnxk: add NPA pool HW operations")
Signed-off-by: Amiya Ranjan Mohakud <[email protected]>
---
drivers/common/cnxk/roc_nix_queue.c | 5 +++
drivers/common/cnxk/roc_npa.c | 46 ++++++++++++++++++++++++-
drivers/common/cnxk/roc_npa.h | 1 +
drivers/mempool/cnxk/cnxk_mempool_ops.c | 5 +++
4 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/drivers/common/cnxk/roc_nix_queue.c
b/drivers/common/cnxk/roc_nix_queue.c
index 075c9c1591..879cb217c0 100644
--- a/drivers/common/cnxk/roc_nix_queue.c
+++ b/drivers/common/cnxk/roc_nix_queue.c
@@ -1666,6 +1666,11 @@ sqb_pool_populate(struct roc_nix *roc_nix, struct
roc_nix_sq *sq)
}
roc_npa_pool_op_range_set(sq->aura_handle, (uint64_t)sq->sqe_mem, iova);
+
+ rc = roc_npa_pool_range_int_enable(sq->aura_handle);
+ if (rc)
+ goto npa_fail;
+
roc_npa_aura_limit_modify(sq->aura_handle, nb_sqb_bufs);
sq->aura_sqb_bufs = nb_sqb_bufs;
diff --git a/drivers/common/cnxk/roc_npa.c b/drivers/common/cnxk/roc_npa.c
index 4a3e96a97a..6209f1676b 100644
--- a/drivers/common/cnxk/roc_npa.c
+++ b/drivers/common/cnxk/roc_npa.c
@@ -738,7 +738,12 @@ npa_aura_pool_pair_alloc(struct npa_lf *lf, const uint32_t
block_size,
pool->ptr_end = ~0;
pool->stack_caching = 1;
pool->err_int_ena = BIT(NPA_POOL_ERR_INT_OVFLS);
- pool->err_int_ena |= BIT(NPA_POOL_ERR_INT_RANGE);
+ /* NPA_POOL_ERR_INT_RANGE omitted: ptr_start/ptr_end are initialized to
+ * 0/~0 and the actual IOVA range is set later via
roc_npa_pool_op_range_set().
+ * On CN10K the RANGE interrupt fires spuriously in the window between
pool
+ * creation and the range update, causing pool stack drain. Mask it
here
+ * and rely on the range being set correctly before any alloc/free.
+ */
pool->err_int_ena |= BIT(NPA_POOL_ERR_INT_PERR);
pool->avg_con = 0;
@@ -1171,6 +1176,45 @@ roc_npa_aura_destroy(uint64_t aura_handle)
return rc;
}
+int
+roc_npa_pool_range_int_enable(uint64_t aura_handle)
+{
+ struct npa_cn20k_aq_enq_req *pool_req_cn20k;
+ struct npa_aq_enq_req *pool_req;
+ struct npa_lf *lf;
+ struct mbox *mbox;
+ int rc;
+
+ lf = idev_npa_obj_get();
+ if (lf == NULL)
+ return NPA_ERR_DEVICE_NOT_BOUNDED;
+
+ mbox = mbox_get(lf->mbox);
+ if (roc_model_is_cn20k()) {
+ pool_req_cn20k = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
+ pool_req = (struct npa_aq_enq_req *)pool_req_cn20k;
+ } else {
+ pool_req = mbox_alloc_msg_npa_aq_enq(mbox);
+ }
+ if (pool_req == NULL) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ pool_req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
+ pool_req->ctype = NPA_AQ_CTYPE_POOL;
+ pool_req->op = NPA_AQ_INSTOP_WRITE;
+ pool_req->pool.err_int_ena = BIT(NPA_POOL_ERR_INT_OVFLS) |
+ BIT(NPA_POOL_ERR_INT_RANGE) |
+ BIT(NPA_POOL_ERR_INT_PERR);
+ pool_req->pool_mask.err_int_ena = ~pool_req->pool_mask.err_int_ena;
+
+ rc = mbox_process(mbox);
+exit:
+ mbox_put(mbox);
+ return rc;
+}
+
int
roc_npa_pool_range_update_check(uint64_t aura_handle)
{
diff --git a/drivers/common/cnxk/roc_npa.h b/drivers/common/cnxk/roc_npa.h
index db610cbd2c..8555765db8 100644
--- a/drivers/common/cnxk/roc_npa.h
+++ b/drivers/common/cnxk/roc_npa.h
@@ -852,6 +852,7 @@ int __roc_api roc_npa_aura_limit_modify(uint64_t
aura_handle,
uint16_t aura_limit);
int __roc_api roc_npa_pool_destroy(uint64_t aura_handle);
int __roc_api roc_npa_pool_range_update_check(uint64_t aura_handle);
+int __roc_api roc_npa_pool_range_int_enable(uint64_t aura_handle);
void __roc_api roc_npa_aura_op_range_set(uint64_t aura_handle,
uint64_t start_iova,
uint64_t end_iova);
diff --git a/drivers/mempool/cnxk/cnxk_mempool_ops.c
b/drivers/mempool/cnxk/cnxk_mempool_ops.c
index 01b6247fbb..7e81f4347d 100644
--- a/drivers/mempool/cnxk/cnxk_mempool_ops.c
+++ b/drivers/mempool/cnxk/cnxk_mempool_ops.c
@@ -2,6 +2,7 @@
* Copyright(C) 2021 Marvell.
*/
+#include <rte_eal.h>
#include <rte_mbuf_pool_ops.h>
#include <rte_mempool.h>
@@ -180,6 +181,10 @@ cnxk_mempool_populate(struct rte_mempool *mp, unsigned int
max_objs,
if (roc_npa_pool_range_update_check(mp->pool_id) < 0)
return -EBUSY;
+ if (rte_eal_iova_mode() == RTE_IOVA_VA &&
+ roc_npa_pool_range_int_enable(mp->pool_id) < 0)
+ return -EBUSY;
+
return rte_mempool_op_populate_helper(
mp, RTE_MEMPOOL_POPULATE_F_ALIGN_OBJ, max_objs, vaddr, iova,
len, obj_cb, obj_cb_arg);
--
2.39.5 (Apple Git-154)