ixgbe_tx_queue_release_mbufs(struct ixgbe_tx_queue *txq) { unsigned i; struct ixgbe_tx_entry_v *txe; uint16_t nb_free, max_desc; if (txq->sw_ring != NULL) { /* release the used mbufs in sw_ring */ nb_free = txq->nb_tx_free; max_desc = (uint16_t)(txq->nb_tx_desc - 1); for (i = txq->tx_next_dd - (txq->tx_rs_thresh - 1); nb_free < max_desc && i != txq->tx_tail; i = (i + 1) & max_desc) { txe = (struct ixgbe_tx_entry_v *)&txq->sw_ring[i]; /* * Check for already freed packets. * Note: ixgbe_tx_free_bufs does not NULL after free, * so we actually have to check the reference count. */ if (txe->mbuf != NULL && rte_mbuf_refcnt_read(txe->mbuf) != 0) rte_pktmbuf_free_seg(txe->mbuf); } /* reset tx_entry */ for (i = 0; i < txq->nb_tx_desc; i++) { txe = (struct ixgbe_tx_entry_v *)&txq->sw_ring[i]; txe->mbuf = NULL; } } }
uint16_t rte_mbuf_refcnt_read_export(struct rte_mbuf* m) { return rte_mbuf_refcnt_read(m); }