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)

Reply via email to