Added packet memory prefetch for faster access to variables inside packet buffer needed for the free operation.
Signed-off-by: Mike A. Polehn <mike.a.polehn at intel.com> diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c index 177fb2e..d9bc30a 100644 --- a/drivers/net/i40e/i40e_rxtx.c +++ b/drivers/net/i40e/i40e_rxtx.c @@ -1748,7 +1748,8 @@ static inline int __attribute__((always_inline)) i40e_tx_free_bufs(struct i40e_tx_queue *txq) { struct i40e_tx_entry *txep; - uint16_t i; + unsigned i, l, tx_rs_thresh; + struct rte_mbuf *pk, *pk_next; if ((txq->tx_ring[txq->tx_next_dd].cmd_type_offset_bsz & rte_cpu_to_le_64(I40E_TXD_QW1_DTYPE_MASK)) != @@ -1757,18 +1758,46 @@ i40e_tx_free_bufs(struct i40e_tx_queue *txq) txep = &(txq->sw_ring[txq->tx_next_dd - (txq->tx_rs_thresh - 1)]); - for (i = 0; i < txq->tx_rs_thresh; i++) - rte_prefetch0((txep + i)->mbuf); + /* Prefetch first 2 packets */ + pk = txep->mbuf; + rte_prefetch0(pk); + txep->mbuf = NULL; + txep++; + tx_rs_thresh = txq->tx_rs_thresh; + if (likely(txq->tx_rs_thresh > 1)) { + pk_next = txep->mbuf; + rte_prefetch0(pk_next); + txep->mbuf = NULL; + txep++; + l = tx_rs_thresh - 2; + } else { + pk_next = pk; + l = tx_rs_thresh - 1; + } if (!(txq->txq_flags & (uint32_t)ETH_TXQ_FLAGS_NOREFCOUNT)) { - for (i = 0; i < txq->tx_rs_thresh; ++i, ++txep) { - rte_mempool_put(txep->mbuf->pool, txep->mbuf); - txep->mbuf = NULL; + for (i = 0; i < tx_rs_thresh; ++i) { + struct rte_mbuf *mbuf = pk; + pk = pk_next; + if (likely(i < l)) { + pk_next = txep->mbuf; + rte_prefetch0(pk_next); + txep->mbuf = NULL; + txep++; + } + rte_mempool_put(mbuf->pool, mbuf); } } else { - for (i = 0; i < txq->tx_rs_thresh; ++i, ++txep) { - rte_pktmbuf_free_seg(txep->mbuf); - txep->mbuf = NULL; + for (i = 0; i < tx_rs_thresh; ++i) { + struct rte_mbuf *mbuf = pk; + pk = pk_next; + if (likely(i < l)) { + pk_next = txep->mbuf; + rte_prefetch0(pk_next); + txep->mbuf = NULL; + txep++; + } + rte_pktmbuf_free_seg(mbuf); } }