From: Neel Patel <neel.pa...@amd.com>

They can be batched together this way, reducing the number
of PCIe transactions. This improves transmit PPS by up to 50% in
some configurations.

Signed-off-by: Andrew Boyer <andrew.bo...@amd.com>
Signed-off-by: Neel Patel <neel.pa...@amd.com>
---
 drivers/net/ionic/ionic_dev.c         |  9 +++--
 drivers/net/ionic/ionic_dev.h         |  6 ++-
 drivers/net/ionic/ionic_lif.c         | 26 +++++++++----
 drivers/net/ionic/ionic_rxtx.h        | 56 +++++++++++++++++++++++++++
 drivers/net/ionic/ionic_rxtx_sg.c     | 18 ++++-----
 drivers/net/ionic/ionic_rxtx_simple.c | 18 ++++-----
 6 files changed, 101 insertions(+), 32 deletions(-)

diff --git a/drivers/net/ionic/ionic_dev.c b/drivers/net/ionic/ionic_dev.c
index 70c14882ed..7f15914f74 100644
--- a/drivers/net/ionic/ionic_dev.c
+++ b/drivers/net/ionic/ionic_dev.c
@@ -369,17 +369,19 @@ ionic_q_init(struct ionic_queue *q, uint32_t index, 
uint16_t num_descs)
        q->index = index;
        q->num_descs = num_descs;
        q->size_mask = num_descs - 1;
-       q->head_idx = 0;
-       q->tail_idx = 0;
+       ionic_q_reset(q);
 
        return 0;
 }
 
 void
-ionic_q_map(struct ionic_queue *q, void *base, rte_iova_t base_pa)
+ionic_q_map(struct ionic_queue *q, void *base, rte_iova_t base_pa,
+                       void *cmb_base, rte_iova_t cmb_base_pa)
 {
        q->base = base;
        q->base_pa = base_pa;
+       q->cmb_base = cmb_base;
+       q->cmb_base_pa = cmb_base_pa;
 }
 
 void
@@ -393,5 +395,6 @@ void
 ionic_q_reset(struct ionic_queue *q)
 {
        q->head_idx = 0;
+       q->cmb_head_idx = 0;
        q->tail_idx = 0;
 }
diff --git a/drivers/net/ionic/ionic_dev.h b/drivers/net/ionic/ionic_dev.h
index 971c261b27..3a366247f1 100644
--- a/drivers/net/ionic/ionic_dev.h
+++ b/drivers/net/ionic/ionic_dev.h
@@ -145,11 +145,13 @@ struct ionic_queue {
        uint16_t num_descs;
        uint16_t num_segs;
        uint16_t head_idx;
+       uint16_t cmb_head_idx;
        uint16_t tail_idx;
        uint16_t size_mask;
        uint8_t type;
        uint8_t hw_type;
        void *base;
+       void *cmb_base;
        void *sg_base;
        struct ionic_doorbell __iomem *db;
        void **info;
@@ -158,6 +160,7 @@ struct ionic_queue {
        uint32_t hw_index;
        rte_iova_t base_pa;
        rte_iova_t sg_base_pa;
+       rte_iova_t cmb_base_pa;
 };
 
 #define IONIC_INTR_NONE                (-1)
@@ -244,7 +247,8 @@ uint32_t ionic_cq_service(struct ionic_cq *cq, uint32_t 
work_to_do,
 
 int ionic_q_init(struct ionic_queue *q, uint32_t index, uint16_t num_descs);
 void ionic_q_reset(struct ionic_queue *q);
-void ionic_q_map(struct ionic_queue *q, void *base, rte_iova_t base_pa);
+void ionic_q_map(struct ionic_queue *q, void *base, rte_iova_t base_pa,
+                                void *cmb_base, rte_iova_t cmb_base_pa);
 void ionic_q_sg_map(struct ionic_queue *q, void *base, rte_iova_t base_pa);
 
 static inline uint16_t
diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
index fe2112c057..2713f8aa24 100644
--- a/drivers/net/ionic/ionic_lif.c
+++ b/drivers/net/ionic/ionic_lif.c
@@ -572,10 +572,11 @@ ionic_qcq_alloc(struct ionic_lif *lif,
 {
        struct ionic_qcq *new;
        uint32_t q_size, cq_size, sg_size, total_size;
-       void *q_base, *cq_base, *sg_base;
+       void *q_base, *cmb_q_base, *cq_base, *sg_base;
        rte_iova_t q_base_pa = 0;
        rte_iova_t cq_base_pa = 0;
        rte_iova_t sg_base_pa = 0;
+       rte_iova_t cmb_q_base_pa = 0;
        size_t page_size = rte_mem_page_size();
        int err;
 
@@ -666,19 +667,22 @@ ionic_qcq_alloc(struct ionic_lif *lif,
                        IONIC_PRINT(ERR, "Cannot reserve queue from NIC mem");
                        return -ENOMEM;
                }
-               q_base = (void *)
+               cmb_q_base = (void *)
                        ((uintptr_t)lif->adapter->bars.bar[2].vaddr +
                         (uintptr_t)lif->adapter->cmb_offset);
                /* CMB PA is a relative address */
-               q_base_pa = lif->adapter->cmb_offset;
+               cmb_q_base_pa = lif->adapter->cmb_offset;
                lif->adapter->cmb_offset += q_size;
+       } else {
+               cmb_q_base = NULL;
+               cmb_q_base_pa = 0;
        }
 
        IONIC_PRINT(DEBUG, "Q-Base-PA = %#jx CQ-Base-PA = %#jx "
                "SG-base-PA = %#jx",
                q_base_pa, cq_base_pa, sg_base_pa);
 
-       ionic_q_map(&new->q, q_base, q_base_pa);
+       ionic_q_map(&new->q, q_base, q_base_pa, cmb_q_base, cmb_q_base_pa);
        ionic_cq_map(&new->cq, cq_base, cq_base_pa);
 
        *qcq = new;
@@ -1583,7 +1587,6 @@ ionic_lif_txq_init(struct ionic_tx_qcq *txq)
                        .flags = rte_cpu_to_le_16(IONIC_QINIT_F_ENA),
                        .intr_index = rte_cpu_to_le_16(IONIC_INTR_NONE),
                        .ring_size = rte_log2_u32(q->num_descs),
-                       .ring_base = rte_cpu_to_le_64(q->base_pa),
                        .cq_ring_base = rte_cpu_to_le_64(cq->base_pa),
                        .sg_ring_base = rte_cpu_to_le_64(q->sg_base_pa),
                },
@@ -1592,8 +1595,12 @@ ionic_lif_txq_init(struct ionic_tx_qcq *txq)
 
        if (txq->flags & IONIC_QCQ_F_SG)
                ctx.cmd.q_init.flags |= rte_cpu_to_le_16(IONIC_QINIT_F_SG);
-       if (txq->flags & IONIC_QCQ_F_CMB)
+       if (txq->flags & IONIC_QCQ_F_CMB) {
                ctx.cmd.q_init.flags |= rte_cpu_to_le_16(IONIC_QINIT_F_CMB);
+               ctx.cmd.q_init.ring_base = rte_cpu_to_le_64(q->cmb_base_pa);
+       } else {
+               ctx.cmd.q_init.ring_base = rte_cpu_to_le_64(q->base_pa);
+       }
 
        IONIC_PRINT(DEBUG, "txq_init.index %d", q->index);
        IONIC_PRINT(DEBUG, "txq_init.ring_base 0x%" PRIx64 "", q->base_pa);
@@ -1638,7 +1645,6 @@ ionic_lif_rxq_init(struct ionic_rx_qcq *rxq)
                        .flags = rte_cpu_to_le_16(IONIC_QINIT_F_ENA),
                        .intr_index = rte_cpu_to_le_16(IONIC_INTR_NONE),
                        .ring_size = rte_log2_u32(q->num_descs),
-                       .ring_base = rte_cpu_to_le_64(q->base_pa),
                        .cq_ring_base = rte_cpu_to_le_64(cq->base_pa),
                        .sg_ring_base = rte_cpu_to_le_64(q->sg_base_pa),
                },
@@ -1647,8 +1653,12 @@ ionic_lif_rxq_init(struct ionic_rx_qcq *rxq)
 
        if (rxq->flags & IONIC_QCQ_F_SG)
                ctx.cmd.q_init.flags |= rte_cpu_to_le_16(IONIC_QINIT_F_SG);
-       if (rxq->flags & IONIC_QCQ_F_CMB)
+       if (rxq->flags & IONIC_QCQ_F_CMB) {
                ctx.cmd.q_init.flags |= rte_cpu_to_le_16(IONIC_QINIT_F_CMB);
+               ctx.cmd.q_init.ring_base = rte_cpu_to_le_64(q->cmb_base_pa);
+       } else {
+               ctx.cmd.q_init.ring_base = rte_cpu_to_le_64(q->base_pa);
+       }
 
        IONIC_PRINT(DEBUG, "rxq_init.index %d", q->index);
        IONIC_PRINT(DEBUG, "rxq_init.ring_base 0x%" PRIx64 "", q->base_pa);
diff --git a/drivers/net/ionic/ionic_rxtx.h b/drivers/net/ionic/ionic_rxtx.h
index 8537141597..5348395956 100644
--- a/drivers/net/ionic/ionic_rxtx.h
+++ b/drivers/net/ionic/ionic_rxtx.h
@@ -77,4 +77,60 @@ uint16_t ionic_xmit_pkts_sg(void *tx_queue, struct rte_mbuf 
**tx_pkts,
 
 int ionic_rx_fill_sg(struct ionic_rx_qcq *rxq);
 
+static inline void
+ionic_rxq_flush(struct ionic_queue *q)
+{
+       struct ionic_rxq_desc *desc_base = q->base;
+       struct ionic_rxq_desc *cmb_desc_base = q->cmb_base;
+
+       if (q->cmb_base) {
+               if (q->head_idx < q->cmb_head_idx) {
+                       /* copy [cmb_head, num_descs) */
+                       rte_memcpy((void *)&cmb_desc_base[q->cmb_head_idx],
+                               (void *)&desc_base[q->cmb_head_idx],
+                               (q->num_descs - q->cmb_head_idx) * 
sizeof(*desc_base));
+                       /* copy [0, head) */
+                       rte_memcpy((void *)&cmb_desc_base[0],
+                               (void *)&desc_base[0],
+                               q->head_idx * sizeof(*desc_base));
+               } else {
+                       /* copy [cmb_head, head) */
+                       rte_memcpy((void *)&cmb_desc_base[q->cmb_head_idx],
+                               (void *)&desc_base[q->cmb_head_idx],
+                               (q->head_idx - q->cmb_head_idx) * 
sizeof(*desc_base));
+               }
+               q->cmb_head_idx = q->head_idx;
+       }
+
+       ionic_q_flush(q);
+}
+
+static inline void
+ionic_txq_flush(struct ionic_queue *q)
+{
+       struct ionic_txq_desc *desc_base = q->base;
+       struct ionic_txq_desc *cmb_desc_base = q->cmb_base;
+
+       if (q->cmb_base) {
+               if (q->head_idx < q->cmb_head_idx) {
+                       /* copy [cmb_head, num_descs) */
+                       rte_memcpy((void *)&cmb_desc_base[q->cmb_head_idx],
+                               (void *)&desc_base[q->cmb_head_idx],
+                               (q->num_descs - q->cmb_head_idx) * 
sizeof(*desc_base));
+                       /* copy [0, head) */
+                       rte_memcpy((void *)&cmb_desc_base[0],
+                               (void *)&desc_base[0],
+                               q->head_idx * sizeof(*desc_base));
+               } else {
+                       /* copy [cmb_head, head) */
+                       rte_memcpy((void *)&cmb_desc_base[q->cmb_head_idx],
+                               (void *)&desc_base[q->cmb_head_idx],
+                               (q->head_idx - q->cmb_head_idx) * 
sizeof(*desc_base));
+               }
+               q->cmb_head_idx = q->head_idx;
+       }
+
+       ionic_q_flush(q);
+}
+
 #endif /* _IONIC_RXTX_H_ */
diff --git a/drivers/net/ionic/ionic_rxtx_sg.c 
b/drivers/net/ionic/ionic_rxtx_sg.c
index 1392342463..92e1d6e259 100644
--- a/drivers/net/ionic/ionic_rxtx_sg.c
+++ b/drivers/net/ionic/ionic_rxtx_sg.c
@@ -166,6 +166,7 @@ ionic_xmit_pkts_sg(void *tx_queue, struct rte_mbuf 
**tx_pkts,
 {
        struct ionic_tx_qcq *txq = tx_queue;
        struct ionic_queue *q = &txq->qcq.q;
+       struct ionic_txq_desc *desc_base = q->base;
        struct ionic_tx_stats *stats = &txq->stats;
        struct rte_mbuf *mbuf;
        uint32_t bytes_tx = 0;
@@ -173,9 +174,7 @@ ionic_xmit_pkts_sg(void *tx_queue, struct rte_mbuf 
**tx_pkts,
        uint64_t then, now, hz, delta;
        int err;
 
-       struct ionic_txq_desc *desc_base = q->base;
-       if (!(txq->flags & IONIC_QCQ_F_CMB))
-               rte_prefetch0(&desc_base[q->head_idx]);
+       rte_prefetch0(&desc_base[q->head_idx]);
        rte_prefetch0(IONIC_INFO_PTR(q, q->head_idx));
 
        if (nb_pkts) {
@@ -196,8 +195,7 @@ ionic_xmit_pkts_sg(void *tx_queue, struct rte_mbuf 
**tx_pkts,
 
        while (nb_tx < nb_pkts) {
                uint16_t next_idx = Q_NEXT_TO_POST(q, 1);
-               if (!(txq->flags & IONIC_QCQ_F_CMB))
-                       rte_prefetch0(&desc_base[next_idx]);
+               rte_prefetch0(&desc_base[next_idx]);
                rte_prefetch0(IONIC_INFO_PTR(q, next_idx));
 
                if (nb_tx + 1 < nb_pkts) {
@@ -222,7 +220,7 @@ ionic_xmit_pkts_sg(void *tx_queue, struct rte_mbuf 
**tx_pkts,
 
        if (nb_tx > 0) {
                rte_wmb();
-               ionic_q_flush(q);
+               ionic_txq_flush(q);
 
                txq->last_wdog_cycles = rte_get_timer_cycles();
 
@@ -458,8 +456,7 @@ ionic_rxq_service_sg(struct ionic_rx_qcq *rxq, uint32_t 
work_to_do,
                /* Prefetch 4 x 16B comp */
                rte_prefetch0(&cq_desc_base[Q_NEXT_TO_SRVC(cq, 4)]);
                /* Prefetch 4 x 16B descriptors */
-               if (!(rxq->flags & IONIC_QCQ_F_CMB))
-                       rte_prefetch0(&q_desc_base[Q_NEXT_TO_POST(q, 4)]);
+               rte_prefetch0(&q_desc_base[Q_NEXT_TO_POST(q, 4)]);
 
                /* Clean one descriptor */
                ionic_rx_clean_one_sg(rxq, cq_desc, rx_svc);
@@ -478,7 +475,8 @@ ionic_rxq_service_sg(struct ionic_rx_qcq *rxq, uint32_t 
work_to_do,
 
        /* Update the queue indices and ring the doorbell */
        if (work_done) {
-               ionic_q_flush(q);
+               ionic_rxq_flush(q);
+
                rxq->last_wdog_cycles = rte_get_timer_cycles();
                rxq->wdog_ms = IONIC_Q_WDOG_MS;
        } else {
@@ -542,7 +540,7 @@ ionic_rx_fill_sg(struct ionic_rx_qcq *rxq)
                q->head_idx = Q_NEXT_TO_POST(q, 1);
        }
 
-       ionic_q_flush(q);
+       ionic_rxq_flush(q);
 
        return err;
 }
diff --git a/drivers/net/ionic/ionic_rxtx_simple.c 
b/drivers/net/ionic/ionic_rxtx_simple.c
index 00152c885a..f12f66f40c 100644
--- a/drivers/net/ionic/ionic_rxtx_simple.c
+++ b/drivers/net/ionic/ionic_rxtx_simple.c
@@ -139,6 +139,7 @@ ionic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 {
        struct ionic_tx_qcq *txq = tx_queue;
        struct ionic_queue *q = &txq->qcq.q;
+       struct ionic_txq_desc *desc_base = q->base;
        struct ionic_tx_stats *stats = &txq->stats;
        struct rte_mbuf *mbuf;
        uint32_t bytes_tx = 0;
@@ -146,9 +147,7 @@ ionic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
        uint64_t then, now, hz, delta;
        int err;
 
-       struct ionic_txq_desc *desc_base = q->base;
-       if (!(txq->flags & IONIC_QCQ_F_CMB))
-               rte_prefetch0(&desc_base[q->head_idx]);
+       rte_prefetch0(&desc_base[q->head_idx]);
        rte_prefetch0(&q->info[q->head_idx]);
 
        if (nb_pkts) {
@@ -169,8 +168,7 @@ ionic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 
        while (nb_tx < nb_pkts) {
                uint16_t next_idx = Q_NEXT_TO_POST(q, 1);
-               if (!(txq->flags & IONIC_QCQ_F_CMB))
-                       rte_prefetch0(&desc_base[next_idx]);
+               rte_prefetch0(&desc_base[next_idx]);
                rte_prefetch0(&q->info[next_idx]);
 
                if (nb_tx + 1 < nb_pkts) {
@@ -195,7 +193,7 @@ ionic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 
        if (nb_tx > 0) {
                rte_wmb();
-               ionic_q_flush(q);
+               ionic_txq_flush(q);
 
                txq->last_wdog_cycles = rte_get_timer_cycles();
 
@@ -379,8 +377,7 @@ ionic_rxq_service(struct ionic_rx_qcq *rxq, uint32_t 
work_to_do,
                /* Prefetch 4 x 16B comp */
                rte_prefetch0(&cq_desc_base[Q_NEXT_TO_SRVC(cq, 4)]);
                /* Prefetch 4 x 16B descriptors */
-               if (!(rxq->flags & IONIC_QCQ_F_CMB))
-                       rte_prefetch0(&q_desc_base[Q_NEXT_TO_POST(q, 4)]);
+               rte_prefetch0(&q_desc_base[Q_NEXT_TO_POST(q, 4)]);
 
                /* Clean one descriptor */
                ionic_rx_clean_one(rxq, cq_desc, rx_svc);
@@ -399,7 +396,8 @@ ionic_rxq_service(struct ionic_rx_qcq *rxq, uint32_t 
work_to_do,
 
        /* Update the queue indices and ring the doorbell */
        if (work_done) {
-               ionic_q_flush(q);
+               ionic_rxq_flush(q);
+
                rxq->last_wdog_cycles = rte_get_timer_cycles();
                rxq->wdog_ms = IONIC_Q_WDOG_MS;
        } else {
@@ -463,7 +461,7 @@ ionic_rx_fill(struct ionic_rx_qcq *rxq)
                q->head_idx = Q_NEXT_TO_POST(q, 1);
        }
 
-       ionic_q_flush(q);
+       ionic_rxq_flush(q);
 
        return err;
 }
-- 
2.17.1

Reply via email to