xref: /dpdk/drivers/net/virtio/virtio_rxtx_simple.h (revision 945acb4a0d644d194f1823084a234f9c286dcf8c)
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