| 3101 | } |
| 3102 | |
| 3103 | static int ena_tx_cleanup(void *txp, uint32_t free_pkt_cnt) |
| 3104 | { |
| 3105 | struct rte_mbuf *pkts_to_clean[ENA_CLEANUP_BUF_THRESH]; |
| 3106 | struct ena_ring *tx_ring = (struct ena_ring *)txp; |
| 3107 | size_t mbuf_cnt = 0; |
| 3108 | size_t pkt_cnt = 0; |
| 3109 | unsigned int total_tx_descs = 0; |
| 3110 | unsigned int total_tx_pkts = 0; |
| 3111 | uint16_t cleanup_budget; |
| 3112 | uint16_t next_to_clean = tx_ring->next_to_clean; |
| 3113 | bool fast_free = tx_ring->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE; |
| 3114 | |
| 3115 | /* |
| 3116 | * If free_pkt_cnt is equal to 0, it means that the user requested |
| 3117 | * full cleanup, so attempt to release all Tx descriptors |
| 3118 | * (ring_size - 1 -> size_mask) |
| 3119 | */ |
| 3120 | cleanup_budget = (free_pkt_cnt == 0) ? tx_ring->size_mask : free_pkt_cnt; |
| 3121 | |
| 3122 | while (likely(total_tx_pkts < cleanup_budget)) { |
| 3123 | struct rte_mbuf *mbuf; |
| 3124 | struct ena_tx_buffer *tx_info; |
| 3125 | uint16_t req_id; |
| 3126 | |
| 3127 | if (ena_com_tx_comp_req_id_get(tx_ring->ena_com_io_cq, &req_id) != 0) |
| 3128 | break; |
| 3129 | |
| 3130 | if (unlikely(validate_tx_req_id(tx_ring, req_id) != 0)) |
| 3131 | break; |
| 3132 | |
| 3133 | /* Get Tx info & store how many descs were processed */ |
| 3134 | tx_info = &tx_ring->tx_buffer_info[req_id]; |
| 3135 | tx_info->timestamp = 0; |
| 3136 | |
| 3137 | mbuf = tx_info->mbuf; |
| 3138 | if (fast_free) { |
| 3139 | pkts_to_clean[pkt_cnt++] = mbuf; |
| 3140 | mbuf_cnt += mbuf->nb_segs; |
| 3141 | if (mbuf_cnt >= ENA_CLEANUP_BUF_THRESH) { |
| 3142 | rte_pktmbuf_free_bulk(pkts_to_clean, pkt_cnt); |
| 3143 | mbuf_cnt = 0; |
| 3144 | pkt_cnt = 0; |
| 3145 | } |
| 3146 | } else { |
| 3147 | rte_pktmbuf_free(mbuf); |
| 3148 | } |
| 3149 | |
| 3150 | tx_info->mbuf = NULL; |
| 3151 | tx_ring->empty_tx_reqs[next_to_clean] = req_id; |
| 3152 | |
| 3153 | total_tx_descs += tx_info->tx_descs; |
| 3154 | total_tx_pkts++; |
| 3155 | |
| 3156 | /* Put back descriptor to the ring for reuse */ |
| 3157 | next_to_clean = ENA_IDX_NEXT_MASKED(next_to_clean, |
| 3158 | tx_ring->size_mask); |
| 3159 | } |
| 3160 |
no test coverage detected