From: Rakesh Kudurumalla <[email protected]> Add roc_nix_rq_multi_ena_dis() to batch RQ enable/disable mailbox AQ operations and process them in a single mbox_process() call.
Skip mbox_process() when no messages were queued (e.g. all qid are UINT16_MAX) by checking num_msgs and msg_size via mbox_nonempty_nolock(). Signed-off-by: Rakesh Kudurumalla <[email protected]> --- drivers/common/cnxk/roc_mbox_priv.h | 6 +- drivers/common/cnxk/roc_nix.h | 2 + drivers/common/cnxk/roc_nix_queue.c | 102 ++++++++++++++++++ .../common/cnxk/roc_platform_base_symbols.c | 1 + 4 files changed, 107 insertions(+), 4 deletions(-) diff --git a/drivers/common/cnxk/roc_mbox_priv.h b/drivers/common/cnxk/roc_mbox_priv.h index 354c8fa52a..e9da1959b6 100644 --- a/drivers/common/cnxk/roc_mbox_priv.h +++ b/drivers/common/cnxk/roc_mbox_priv.h @@ -113,14 +113,12 @@ mbox_rsp_init(uint16_t mbox_id, void *msghdr) } static inline bool -mbox_nonempty(struct mbox *mbox, int devid) +mbox_nonempty_nolock(struct mbox *mbox, int devid) { struct mbox_dev *mdev = &mbox->dev[devid]; bool ret; - plt_spinlock_lock(&mdev->mbox_lock); - ret = mdev->num_msgs != 0; - plt_spinlock_unlock(&mdev->mbox_lock); + ret = mdev->num_msgs != 0 && mdev->msg_size != 0; return ret; } diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h index 8ba8b3e0b6..f495e2a5ad 100644 --- a/drivers/common/cnxk/roc_nix.h +++ b/drivers/common/cnxk/roc_nix.h @@ -1094,6 +1094,8 @@ int __roc_api roc_nix_rq_modify(struct roc_nix *roc_nix, struct roc_nix_rq *rq, bool ena); int __roc_api roc_nix_rq_cman_config(struct roc_nix *roc_nix, struct roc_nix_rq *rq); int __roc_api roc_nix_rq_ena_dis(struct roc_nix_rq *rq, bool enable); +int __roc_api roc_nix_rq_multi_ena_dis(struct roc_nix *roc_nix, struct roc_nix_rq *rqs, + int nb_rx_queues, bool enable); int __roc_api roc_nix_rq_is_sso_enable(struct roc_nix *roc_nix, uint32_t qid); int __roc_api roc_nix_rq_fini(struct roc_nix_rq *rq); int __roc_api roc_nix_cq_init(struct roc_nix *roc_nix, struct roc_nix_cq *cq); diff --git a/drivers/common/cnxk/roc_nix_queue.c b/drivers/common/cnxk/roc_nix_queue.c index ef9b651022..075c9c1591 100644 --- a/drivers/common/cnxk/roc_nix_queue.c +++ b/drivers/common/cnxk/roc_nix_queue.c @@ -10,6 +10,49 @@ /* Default SQB slack per SQ */ #define ROC_NIX_SQB_SLACK_DFLT 24 +typedef void *(*nix_aq_enq_alloc_t)(struct mbox *mbox); + +static inline void +nix_aq_enq_write_rq_ena(void *msg, uint16_t qid, bool enable) +{ + struct nix_aq_enq_req *aq = msg; + + aq->qidx = qid; + aq->ctype = NIX_AQ_CTYPE_RQ; + aq->op = NIX_AQ_INSTOP_WRITE; + aq->rq.ena = enable; + aq->rq_mask.ena = ~(aq->rq_mask.ena); +} + +static inline int +nix_rq_bulk_ena_dis_fill(struct mbox *mbox, struct roc_nix_rq *rqs, int nb_rx_queues, + bool enable, nix_aq_enq_alloc_t alloc) +{ + int i; + + for (i = 0; i < nb_rx_queues; i++) { + void *aq; + int rc; + + if (rqs[i].qid == UINT16_MAX) + continue; + + aq = alloc(mbox); + if (!aq) { + rc = mbox_process(mbox); + if (rc) + return rc; + aq = alloc(mbox); + if (!aq) + return -ENOSPC; + } + + nix_aq_enq_write_rq_ena(aq, rqs[i].qid, enable); + } + + return 0; +} + static inline uint32_t nix_qsize_to_val(enum nix_q_size qsize) { @@ -47,6 +90,28 @@ nix_rq_vwqe_flush(struct roc_nix_rq *rq, uint16_t vwqe_interval) } } +static int +nix_rq_bulk_ena_dis(struct nix *nix, struct roc_nix_rq *rqs, int nb_rx_queues, bool enable) +{ + struct mbox *mbox = mbox_get((&nix->dev)->mbox); + nix_aq_enq_alloc_t alloc; + int rc; + + if (roc_model_is_cn9k()) + alloc = (nix_aq_enq_alloc_t)mbox_alloc_msg_nix_aq_enq; + else if (roc_model_is_cn10k()) + alloc = (nix_aq_enq_alloc_t)mbox_alloc_msg_nix_cn10k_aq_enq; + else /* CN20K */ + alloc = (nix_aq_enq_alloc_t)mbox_alloc_msg_nix_cn20k_aq_enq; + + rc = nix_rq_bulk_ena_dis_fill(mbox, rqs, nb_rx_queues, enable, alloc); + if (!rc && mbox_nonempty_nolock(mbox, 0)) + rc = mbox_process(mbox); + + mbox_put(mbox); + return rc; +} + int nix_rq_ena_dis(struct dev *dev, struct roc_nix_rq *rq, bool enable) { @@ -126,6 +191,43 @@ roc_nix_sq_ena_dis(struct roc_nix_sq *sq, bool enable) return rc; } +int +roc_nix_rq_multi_ena_dis(struct roc_nix *roc_nix, struct roc_nix_rq *rqs, int nb_rx_queues, + bool enable) +{ + struct nix *nix = roc_nix_to_nix_priv(roc_nix); + struct roc_nix_rq *rq; + int rc, i; + + rc = nix_rq_bulk_ena_dis(nix, rqs, nb_rx_queues, enable); + if (rc) { + plt_err("Failed to %s Rx queues rc=%d pf=%d vf=%d nb_rx_queues=%d", + enable ? "enable" : "disable", rc, nix->dev.pf, nix->dev.vf, + nb_rx_queues); + return rc; + } + + for (i = 0; i < nb_rx_queues; i++) { + rq = &rqs[i]; + + if (rq->qid == UINT16_MAX) + continue; + + nix_rq_vwqe_flush(rq, nix->vwqe_interval); + + /* Check for meta aura if RQ is enabled */ + if (enable && nix->need_meta_aura) { + rc = roc_nix_inl_meta_aura_check(rq->roc_nix, rq); + if (rc) { + plt_err("Failed meta aura check for rq=%u rc=%d pf=%d vf=%d", + rq->qid, rc, nix->dev.pf, nix->dev.vf); + return rc; + } + } + } + return 0; +} + int roc_nix_rq_ena_dis(struct roc_nix_rq *rq, bool enable) { diff --git a/drivers/common/cnxk/roc_platform_base_symbols.c b/drivers/common/cnxk/roc_platform_base_symbols.c index ed34d4b05b..08b2f4c6f8 100644 --- a/drivers/common/cnxk/roc_platform_base_symbols.c +++ b/drivers/common/cnxk/roc_platform_base_symbols.c @@ -353,6 +353,7 @@ RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_rq_ena_dis) RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_rq_is_sso_enable) RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_rq_init) RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_rq_modify) +RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_rq_multi_ena_dis) RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_rq_cman_config) RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_rq_fini) RTE_EXPORT_INTERNAL_SYMBOL(roc_nix_cq_init) -- 2.25.1

