1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2016 Intel Corporation 3 */ 4 5 #ifndef _VIRTIO_RXTX_SIMPLE_H_ 6 #define _VIRTIO_RXTX_SIMPLE_H_ 7 8 #include <stdint.h> 9 10 #include "virtio_logs.h" 11 #include "virtio_ethdev.h" 12 #include "virtqueue.h" 13 #include "virtio_rxtx.h" 14 15 #define RTE_VIRTIO_VPMD_RX_BURST 32 16 #define RTE_VIRTIO_VPMD_RX_REARM_THRESH RTE_VIRTIO_VPMD_RX_BURST 17 18 static inline void 19 virtio_rxq_rearm_vec(struct virtnet_rx *rxvq) 20 { 21 int i; 22 uint16_t desc_idx; 23 struct rte_mbuf **sw_ring; 24 struct vring_desc *start_dp; 25 int ret; 26 struct virtqueue *vq = rxvq->vq; 27 28 desc_idx = vq->vq_avail_idx & (vq->vq_nentries - 1); 29 sw_ring = &vq->sw_ring[desc_idx]; 30 start_dp = &vq->vq_ring.desc[desc_idx]; 31 32 ret = rte_mempool_get_bulk(rxvq->mpool, (void **)sw_ring, 33 RTE_VIRTIO_VPMD_RX_REARM_THRESH); 34 if (unlikely(ret)) { 35 rte_eth_devices[rxvq->port_id].data->rx_mbuf_alloc_failed += 36 RTE_VIRTIO_VPMD_RX_REARM_THRESH; 37 return; 38 } 39 40 for (i = 0; i < RTE_VIRTIO_VPMD_RX_REARM_THRESH; i++) { 41 uintptr_t p; 42 43 p = (uintptr_t)&sw_ring[i]->rearm_data; 44 *(uint64_t *)p = rxvq->mbuf_initializer; 45 46 start_dp[i].addr = 47 VIRTIO_MBUF_ADDR(sw_ring[i], vq) + 48 RTE_PKTMBUF_HEADROOM - vq->hw->vtnet_hdr_size; 49 start_dp[i].len = sw_ring[i]->buf_len - 50 RTE_PKTMBUF_HEADROOM + vq->hw->vtnet_hdr_size; 51 } 52 53 vq->vq_avail_idx += RTE_VIRTIO_VPMD_RX_REARM_THRESH; 54 vq->vq_free_cnt -= RTE_VIRTIO_VPMD_RX_REARM_THRESH; 55 vq_update_avail_idx(vq); 56 } 57 58 #define VIRTIO_TX_FREE_THRESH 32 59 #define VIRTIO_TX_MAX_FREE_BUF_SZ 32 60 #define VIRTIO_TX_FREE_NR 32 61 /* TODO: vq->tx_free_cnt could mean num of free slots so we could avoid shift */ 62 static inline void 63 virtio_xmit_cleanup(struct virtqueue *vq) 64 { 65 uint16_t i, desc_idx; 66 uint32_t nb_free = 0; 67 struct rte_mbuf *m, *free[VIRTIO_TX_MAX_FREE_BUF_SZ]; 68 69 desc_idx = (uint16_t)(vq->vq_used_cons_idx & 70 ((vq->vq_nentries >> 1) - 1)); 71 m = (struct rte_mbuf *)vq->vq_descx[desc_idx++].cookie; 72 m = rte_pktmbuf_prefree_seg(m); 73 if (likely(m != NULL)) { 74 free[0] = m; 75 nb_free = 1; 76 for (i = 1; i < VIRTIO_TX_FREE_NR; i++) { 77 m = (struct rte_mbuf *)vq->vq_descx[desc_idx++].cookie; 78 m = rte_pktmbuf_prefree_seg(m); 79 if (likely(m != NULL)) { 80 if (likely(m->pool == free[0]->pool)) 81 free[nb_free++] = m; 82 else { 83 rte_mempool_put_bulk(free[0]->pool, 84 (void **)free, 85 RTE_MIN(RTE_DIM(free), 86 nb_free)); 87 free[0] = m; 88 nb_free = 1; 89 } 90 } 91 } 92 rte_mempool_put_bulk(free[0]->pool, (void **)free, 93 RTE_MIN(RTE_DIM(free), nb_free)); 94 } else { 95 for (i = 1; i < VIRTIO_TX_FREE_NR; i++) { 96 m = (struct rte_mbuf *)vq->vq_descx[desc_idx++].cookie; 97 m = rte_pktmbuf_prefree_seg(m); 98 if (m != NULL) 99 rte_mempool_put(m->pool, m); 100 } 101 } 102 103 vq->vq_used_cons_idx += VIRTIO_TX_FREE_NR; 104 vq->vq_free_cnt += (VIRTIO_TX_FREE_NR << 1); 105 } 106 107 #endif /* _VIRTIO_RXTX_SIMPLE_H_ */ 108