[PATCH] common/cnxk: fix NPA pool RANGE interrupt handling
From: Amiya Ranjan Mohakud <hidden>
Date: 2026-09-13 04:08:14
Subsystem:
the rest · Maintainer:
Linus Torvalds
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 <redacted>
---
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)