xref: /f-stack/dpdk/lib/librte_vhost/virtio_net.c (revision 16d80a6d)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2016 Intel Corporation
3  */
4 
5 #include <stdint.h>
6 #include <stdbool.h>
7 #include <linux/virtio_net.h>
8 
9 #include <rte_mbuf.h>
10 #include <rte_memcpy.h>
11 #include <rte_ether.h>
12 #include <rte_ip.h>
13 #include <rte_vhost.h>
14 #include <rte_tcp.h>
15 #include <rte_udp.h>
16 #include <rte_sctp.h>
17 #include <rte_arp.h>
18 #include <rte_spinlock.h>
19 #include <rte_malloc.h>
20 
21 #include "iotlb.h"
22 #include "vhost.h"
23 
24 #define MAX_PKT_BURST 32
25 
26 #define MAX_BATCH_LEN 256
27 
28 static  __rte_always_inline bool
29 rxvq_is_mergeable(struct virtio_net *dev)
30 {
31 	return dev->features & (1ULL << VIRTIO_NET_F_MRG_RXBUF);
32 }
33 
34 static bool
35 is_valid_virt_queue_idx(uint32_t idx, int is_tx, uint32_t nr_vring)
36 {
37 	return (is_tx ^ (idx & 1)) == 0 && idx < nr_vring;
38 }
39 
40 static __rte_always_inline void *
41 alloc_copy_ind_table(struct virtio_net *dev, struct vhost_virtqueue *vq,
42 		uint64_t desc_addr, uint64_t desc_len)
43 {
44 	void *idesc;
45 	uint64_t src, dst;
46 	uint64_t len, remain = desc_len;
47 
48 	idesc = rte_malloc(__func__, desc_len, 0);
49 	if (unlikely(!idesc))
50 		return 0;
51 
52 	dst = (uint64_t)(uintptr_t)idesc;
53 
54 	while (remain) {
55 		len = remain;
56 		src = vhost_iova_to_vva(dev, vq, desc_addr, &len,
57 				VHOST_ACCESS_RO);
58 		if (unlikely(!src || !len)) {
59 			rte_free(idesc);
60 			return 0;
61 		}
62 
63 		rte_memcpy((void *)(uintptr_t)dst, (void *)(uintptr_t)src, len);
64 
65 		remain -= len;
66 		dst += len;
67 		desc_addr += len;
68 	}
69 
70 	return idesc;
71 }
72 
73 static __rte_always_inline void
74 free_ind_table(void *idesc)
75 {
76 	rte_free(idesc);
77 }
78 
79 static __rte_always_inline void
80 do_flush_shadow_used_ring_split(struct virtio_net *dev,
81 			struct vhost_virtqueue *vq,
82 			uint16_t to, uint16_t from, uint16_t size)
83 {
84 	rte_memcpy(&vq->used->ring[to],
85 			&vq->shadow_used_split[from],
86 			size * sizeof(struct vring_used_elem));
87 	vhost_log_cache_used_vring(dev, vq,
88 			offsetof(struct vring_used, ring[to]),
89 			size * sizeof(struct vring_used_elem));
90 }
91 
92 static __rte_always_inline void
93 flush_shadow_used_ring_split(struct virtio_net *dev, struct vhost_virtqueue *vq)
94 {
95 	uint16_t used_idx = vq->last_used_idx & (vq->size - 1);
96 
97 	if (used_idx + vq->shadow_used_idx <= vq->size) {
98 		do_flush_shadow_used_ring_split(dev, vq, used_idx, 0,
99 					  vq->shadow_used_idx);
100 	} else {
101 		uint16_t size;
102 
103 		/* update used ring interval [used_idx, vq->size] */
104 		size = vq->size - used_idx;
105 		do_flush_shadow_used_ring_split(dev, vq, used_idx, 0, size);
106 
107 		/* update the left half used ring interval [0, left_size] */
108 		do_flush_shadow_used_ring_split(dev, vq, 0, size,
109 					  vq->shadow_used_idx - size);
110 	}
111 	vq->last_used_idx += vq->shadow_used_idx;
112 
113 	rte_smp_wmb();
114 
115 	vhost_log_cache_sync(dev, vq);
116 
117 	*(volatile uint16_t *)&vq->used->idx += vq->shadow_used_idx;
118 	vq->shadow_used_idx = 0;
119 	vhost_log_used_vring(dev, vq, offsetof(struct vring_used, idx),
120 		sizeof(vq->used->idx));
121 }
122 
123 static __rte_always_inline void
124 update_shadow_used_ring_split(struct vhost_virtqueue *vq,
125 			 uint16_t desc_idx, uint32_t len)
126 {
127 	uint16_t i = vq->shadow_used_idx++;
128 
129 	vq->shadow_used_split[i].id  = desc_idx;
130 	vq->shadow_used_split[i].len = len;
131 }
132 
133 static __rte_always_inline void
134 flush_shadow_used_ring_packed(struct virtio_net *dev,
135 			struct vhost_virtqueue *vq)
136 {
137 	int i;
138 	uint16_t used_idx = vq->last_used_idx;
139 
140 	/* Split loop in two to save memory barriers */
141 	for (i = 0; i < vq->shadow_used_idx; i++) {
142 		vq->desc_packed[used_idx].id = vq->shadow_used_packed[i].id;
143 		vq->desc_packed[used_idx].len = vq->shadow_used_packed[i].len;
144 
145 		used_idx += vq->shadow_used_packed[i].count;
146 		if (used_idx >= vq->size)
147 			used_idx -= vq->size;
148 	}
149 
150 	rte_smp_wmb();
151 
152 	for (i = 0; i < vq->shadow_used_idx; i++) {
153 		uint16_t flags;
154 
155 		if (vq->shadow_used_packed[i].len)
156 			flags = VRING_DESC_F_WRITE;
157 		else
158 			flags = 0;
159 
160 		if (vq->used_wrap_counter) {
161 			flags |= VRING_DESC_F_USED;
162 			flags |= VRING_DESC_F_AVAIL;
163 		} else {
164 			flags &= ~VRING_DESC_F_USED;
165 			flags &= ~VRING_DESC_F_AVAIL;
166 		}
167 
168 		vq->desc_packed[vq->last_used_idx].flags = flags;
169 
170 		vhost_log_cache_used_vring(dev, vq,
171 					vq->last_used_idx *
172 					sizeof(struct vring_packed_desc),
173 					sizeof(struct vring_packed_desc));
174 
175 		vq->last_used_idx += vq->shadow_used_packed[i].count;
176 		if (vq->last_used_idx >= vq->size) {
177 			vq->used_wrap_counter ^= 1;
178 			vq->last_used_idx -= vq->size;
179 		}
180 	}
181 
182 	rte_smp_wmb();
183 	vq->shadow_used_idx = 0;
184 	vhost_log_cache_sync(dev, vq);
185 }
186 
187 static __rte_always_inline void
188 update_shadow_used_ring_packed(struct vhost_virtqueue *vq,
189 			 uint16_t desc_idx, uint32_t len, uint16_t count)
190 {
191 	uint16_t i = vq->shadow_used_idx++;
192 
193 	vq->shadow_used_packed[i].id  = desc_idx;
194 	vq->shadow_used_packed[i].len = len;
195 	vq->shadow_used_packed[i].count = count;
196 }
197 
198 static inline void
199 do_data_copy_enqueue(struct virtio_net *dev, struct vhost_virtqueue *vq)
200 {
201 	struct batch_copy_elem *elem = vq->batch_copy_elems;
202 	uint16_t count = vq->batch_copy_nb_elems;
203 	int i;
204 
205 	for (i = 0; i < count; i++) {
206 		rte_memcpy(elem[i].dst, elem[i].src, elem[i].len);
207 		vhost_log_cache_write(dev, vq, elem[i].log_addr, elem[i].len);
208 		PRINT_PACKET(dev, (uintptr_t)elem[i].dst, elem[i].len, 0);
209 	}
210 
211 	vq->batch_copy_nb_elems = 0;
212 }
213 
214 static inline void
215 do_data_copy_dequeue(struct vhost_virtqueue *vq)
216 {
217 	struct batch_copy_elem *elem = vq->batch_copy_elems;
218 	uint16_t count = vq->batch_copy_nb_elems;
219 	int i;
220 
221 	for (i = 0; i < count; i++)
222 		rte_memcpy(elem[i].dst, elem[i].src, elem[i].len);
223 
224 	vq->batch_copy_nb_elems = 0;
225 }
226 
227 /* avoid write operation when necessary, to lessen cache issues */
228 #define ASSIGN_UNLESS_EQUAL(var, val) do {	\
229 	if ((var) != (val))			\
230 		(var) = (val);			\
231 } while (0)
232 
233 static __rte_always_inline void
234 virtio_enqueue_offload(struct rte_mbuf *m_buf, struct virtio_net_hdr *net_hdr)
235 {
236 	uint64_t csum_l4 = m_buf->ol_flags & PKT_TX_L4_MASK;
237 
238 	if (m_buf->ol_flags & PKT_TX_TCP_SEG)
239 		csum_l4 |= PKT_TX_TCP_CKSUM;
240 
241 	if (csum_l4) {
242 		net_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
243 		net_hdr->csum_start = m_buf->l2_len + m_buf->l3_len;
244 
245 		switch (csum_l4) {
246 		case PKT_TX_TCP_CKSUM:
247 			net_hdr->csum_offset = (offsetof(struct tcp_hdr,
248 						cksum));
249 			break;
250 		case PKT_TX_UDP_CKSUM:
251 			net_hdr->csum_offset = (offsetof(struct udp_hdr,
252 						dgram_cksum));
253 			break;
254 		case PKT_TX_SCTP_CKSUM:
255 			net_hdr->csum_offset = (offsetof(struct sctp_hdr,
256 						cksum));
257 			break;
258 		}
259 	} else {
260 		ASSIGN_UNLESS_EQUAL(net_hdr->csum_start, 0);
261 		ASSIGN_UNLESS_EQUAL(net_hdr->csum_offset, 0);
262 		ASSIGN_UNLESS_EQUAL(net_hdr->flags, 0);
263 	}
264 
265 	/* IP cksum verification cannot be bypassed, then calculate here */
266 	if (m_buf->ol_flags & PKT_TX_IP_CKSUM) {
267 		struct ipv4_hdr *ipv4_hdr;
268 
269 		ipv4_hdr = rte_pktmbuf_mtod_offset(m_buf, struct ipv4_hdr *,
270 						   m_buf->l2_len);
271 		ipv4_hdr->hdr_checksum = rte_ipv4_cksum(ipv4_hdr);
272 	}
273 
274 	if (m_buf->ol_flags & PKT_TX_TCP_SEG) {
275 		if (m_buf->ol_flags & PKT_TX_IPV4)
276 			net_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
277 		else
278 			net_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
279 		net_hdr->gso_size = m_buf->tso_segsz;
280 		net_hdr->hdr_len = m_buf->l2_len + m_buf->l3_len
281 					+ m_buf->l4_len;
282 	} else if (m_buf->ol_flags & PKT_TX_UDP_SEG) {
283 		net_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
284 		net_hdr->gso_size = m_buf->tso_segsz;
285 		net_hdr->hdr_len = m_buf->l2_len + m_buf->l3_len +
286 			m_buf->l4_len;
287 	} else {
288 		ASSIGN_UNLESS_EQUAL(net_hdr->gso_type, 0);
289 		ASSIGN_UNLESS_EQUAL(net_hdr->gso_size, 0);
290 		ASSIGN_UNLESS_EQUAL(net_hdr->hdr_len, 0);
291 	}
292 }
293 
294 static __rte_always_inline int
295 map_one_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
296 		struct buf_vector *buf_vec, uint16_t *vec_idx,
297 		uint64_t desc_iova, uint64_t desc_len, uint8_t perm)
298 {
299 	uint16_t vec_id = *vec_idx;
300 
301 	while (desc_len) {
302 		uint64_t desc_addr;
303 		uint64_t desc_chunck_len = desc_len;
304 
305 		if (unlikely(vec_id >= BUF_VECTOR_MAX))
306 			return -1;
307 
308 		desc_addr = vhost_iova_to_vva(dev, vq,
309 				desc_iova,
310 				&desc_chunck_len,
311 				perm);
312 		if (unlikely(!desc_addr))
313 			return -1;
314 
315 		buf_vec[vec_id].buf_iova = desc_iova;
316 		buf_vec[vec_id].buf_addr = desc_addr;
317 		buf_vec[vec_id].buf_len  = desc_chunck_len;
318 
319 		desc_len -= desc_chunck_len;
320 		desc_iova += desc_chunck_len;
321 		vec_id++;
322 	}
323 	*vec_idx = vec_id;
324 
325 	return 0;
326 }
327 
328 static __rte_always_inline int
329 fill_vec_buf_split(struct virtio_net *dev, struct vhost_virtqueue *vq,
330 			 uint32_t avail_idx, uint16_t *vec_idx,
331 			 struct buf_vector *buf_vec, uint16_t *desc_chain_head,
332 			 uint32_t *desc_chain_len, uint8_t perm)
333 {
334 	uint16_t idx = vq->avail->ring[avail_idx & (vq->size - 1)];
335 	uint16_t vec_id = *vec_idx;
336 	uint32_t len    = 0;
337 	uint64_t dlen;
338 	uint32_t nr_descs = vq->size;
339 	uint32_t cnt    = 0;
340 	struct vring_desc *descs = vq->desc;
341 	struct vring_desc *idesc = NULL;
342 
343 	if (unlikely(idx >= vq->size))
344 		return -1;
345 
346 	*desc_chain_head = idx;
347 
348 	if (vq->desc[idx].flags & VRING_DESC_F_INDIRECT) {
349 		dlen = vq->desc[idx].len;
350 		nr_descs = dlen / sizeof(struct vring_desc);
351 		if (unlikely(nr_descs > vq->size))
352 			return -1;
353 
354 		descs = (struct vring_desc *)(uintptr_t)
355 			vhost_iova_to_vva(dev, vq, vq->desc[idx].addr,
356 						&dlen,
357 						VHOST_ACCESS_RO);
358 		if (unlikely(!descs))
359 			return -1;
360 
361 		if (unlikely(dlen < vq->desc[idx].len)) {
362 			/*
363 			 * The indirect desc table is not contiguous
364 			 * in process VA space, we have to copy it.
365 			 */
366 			idesc = alloc_copy_ind_table(dev, vq,
367 					vq->desc[idx].addr, vq->desc[idx].len);
368 			if (unlikely(!idesc))
369 				return -1;
370 
371 			descs = idesc;
372 		}
373 
374 		idx = 0;
375 	}
376 
377 	while (1) {
378 		if (unlikely(idx >= nr_descs || cnt++ >= nr_descs)) {
379 			free_ind_table(idesc);
380 			return -1;
381 		}
382 
383 		len += descs[idx].len;
384 
385 		if (unlikely(map_one_desc(dev, vq, buf_vec, &vec_id,
386 						descs[idx].addr, descs[idx].len,
387 						perm))) {
388 			free_ind_table(idesc);
389 			return -1;
390 		}
391 
392 		if ((descs[idx].flags & VRING_DESC_F_NEXT) == 0)
393 			break;
394 
395 		idx = descs[idx].next;
396 	}
397 
398 	*desc_chain_len = len;
399 	*vec_idx = vec_id;
400 
401 	if (unlikely(!!idesc))
402 		free_ind_table(idesc);
403 
404 	return 0;
405 }
406 
407 /*
408  * Returns -1 on fail, 0 on success
409  */
410 static inline int
411 reserve_avail_buf_split(struct virtio_net *dev, struct vhost_virtqueue *vq,
412 				uint32_t size, struct buf_vector *buf_vec,
413 				uint16_t *num_buffers, uint16_t avail_head,
414 				uint16_t *nr_vec)
415 {
416 	uint16_t cur_idx;
417 	uint16_t vec_idx = 0;
418 	uint16_t max_tries, tries = 0;
419 
420 	uint16_t head_idx = 0;
421 	uint32_t len = 0;
422 
423 	*num_buffers = 0;
424 	cur_idx  = vq->last_avail_idx;
425 
426 	if (rxvq_is_mergeable(dev))
427 		max_tries = vq->size - 1;
428 	else
429 		max_tries = 1;
430 
431 	while (size > 0) {
432 		if (unlikely(cur_idx == avail_head))
433 			return -1;
434 		/*
435 		 * if we tried all available ring items, and still
436 		 * can't get enough buf, it means something abnormal
437 		 * happened.
438 		 */
439 		if (unlikely(++tries > max_tries))
440 			return -1;
441 
442 		if (unlikely(fill_vec_buf_split(dev, vq, cur_idx,
443 						&vec_idx, buf_vec,
444 						&head_idx, &len,
445 						VHOST_ACCESS_RW) < 0))
446 			return -1;
447 		len = RTE_MIN(len, size);
448 		update_shadow_used_ring_split(vq, head_idx, len);
449 		size -= len;
450 
451 		cur_idx++;
452 		*num_buffers += 1;
453 	}
454 
455 	*nr_vec = vec_idx;
456 
457 	return 0;
458 }
459 
460 static __rte_always_inline int
461 fill_vec_buf_packed_indirect(struct virtio_net *dev,
462 			struct vhost_virtqueue *vq,
463 			struct vring_packed_desc *desc, uint16_t *vec_idx,
464 			struct buf_vector *buf_vec, uint32_t *len, uint8_t perm)
465 {
466 	uint16_t i;
467 	uint32_t nr_descs;
468 	uint16_t vec_id = *vec_idx;
469 	uint64_t dlen;
470 	struct vring_packed_desc *descs, *idescs = NULL;
471 
472 	dlen = desc->len;
473 	descs = (struct vring_packed_desc *)(uintptr_t)
474 		vhost_iova_to_vva(dev, vq, desc->addr, &dlen, VHOST_ACCESS_RO);
475 	if (unlikely(!descs))
476 		return -1;
477 
478 	if (unlikely(dlen < desc->len)) {
479 		/*
480 		 * The indirect desc table is not contiguous
481 		 * in process VA space, we have to copy it.
482 		 */
483 		idescs = alloc_copy_ind_table(dev, vq, desc->addr, desc->len);
484 		if (unlikely(!idescs))
485 			return -1;
486 
487 		descs = idescs;
488 	}
489 
490 	nr_descs =  desc->len / sizeof(struct vring_packed_desc);
491 	if (unlikely(nr_descs >= vq->size)) {
492 		free_ind_table(idescs);
493 		return -1;
494 	}
495 
496 	for (i = 0; i < nr_descs; i++) {
497 		if (unlikely(vec_id >= BUF_VECTOR_MAX)) {
498 			free_ind_table(idescs);
499 			return -1;
500 		}
501 
502 		*len += descs[i].len;
503 		if (unlikely(map_one_desc(dev, vq, buf_vec, &vec_id,
504 						descs[i].addr, descs[i].len,
505 						perm)))
506 			return -1;
507 	}
508 	*vec_idx = vec_id;
509 
510 	if (unlikely(!!idescs))
511 		free_ind_table(idescs);
512 
513 	return 0;
514 }
515 
516 static __rte_always_inline int
517 fill_vec_buf_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,
518 				uint16_t avail_idx, uint16_t *desc_count,
519 				struct buf_vector *buf_vec, uint16_t *vec_idx,
520 				uint16_t *buf_id, uint32_t *len, uint8_t perm)
521 {
522 	bool wrap_counter = vq->avail_wrap_counter;
523 	struct vring_packed_desc *descs = vq->desc_packed;
524 	uint16_t vec_id = *vec_idx;
525 
526 	if (avail_idx < vq->last_avail_idx)
527 		wrap_counter ^= 1;
528 
529 	if (unlikely(!desc_is_avail(&descs[avail_idx], wrap_counter)))
530 		return -1;
531 
532 	/*
533 	 * The ordering between desc flags and desc
534 	 * content reads need to be enforced.
535 	 */
536 	rte_smp_rmb();
537 
538 	*desc_count = 0;
539 	*len = 0;
540 
541 	while (1) {
542 		if (unlikely(vec_id >= BUF_VECTOR_MAX))
543 			return -1;
544 
545 		if (unlikely(*desc_count >= vq->size))
546 			return -1;
547 
548 		*desc_count += 1;
549 		*buf_id = descs[avail_idx].id;
550 
551 		if (descs[avail_idx].flags & VRING_DESC_F_INDIRECT) {
552 			if (unlikely(fill_vec_buf_packed_indirect(dev, vq,
553 							&descs[avail_idx],
554 							&vec_id, buf_vec,
555 							len, perm) < 0))
556 				return -1;
557 		} else {
558 			*len += descs[avail_idx].len;
559 
560 			if (unlikely(map_one_desc(dev, vq, buf_vec, &vec_id,
561 							descs[avail_idx].addr,
562 							descs[avail_idx].len,
563 							perm)))
564 				return -1;
565 		}
566 
567 		if ((descs[avail_idx].flags & VRING_DESC_F_NEXT) == 0)
568 			break;
569 
570 		if (++avail_idx >= vq->size) {
571 			avail_idx -= vq->size;
572 			wrap_counter ^= 1;
573 		}
574 	}
575 
576 	*vec_idx = vec_id;
577 
578 	return 0;
579 }
580 
581 /*
582  * Returns -1 on fail, 0 on success
583  */
584 static inline int
585 reserve_avail_buf_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,
586 				uint32_t size, struct buf_vector *buf_vec,
587 				uint16_t *nr_vec, uint16_t *num_buffers,
588 				uint16_t *nr_descs)
589 {
590 	uint16_t avail_idx;
591 	uint16_t vec_idx = 0;
592 	uint16_t max_tries, tries = 0;
593 
594 	uint16_t buf_id = 0;
595 	uint32_t len = 0;
596 	uint16_t desc_count;
597 
598 	*num_buffers = 0;
599 	avail_idx = vq->last_avail_idx;
600 
601 	if (rxvq_is_mergeable(dev))
602 		max_tries = vq->size - 1;
603 	else
604 		max_tries = 1;
605 
606 	while (size > 0) {
607 		/*
608 		 * if we tried all available ring items, and still
609 		 * can't get enough buf, it means something abnormal
610 		 * happened.
611 		 */
612 		if (unlikely(++tries > max_tries))
613 			return -1;
614 
615 		if (unlikely(fill_vec_buf_packed(dev, vq,
616 						avail_idx, &desc_count,
617 						buf_vec, &vec_idx,
618 						&buf_id, &len,
619 						VHOST_ACCESS_RW) < 0))
620 			return -1;
621 
622 		len = RTE_MIN(len, size);
623 		update_shadow_used_ring_packed(vq, buf_id, len, desc_count);
624 		size -= len;
625 
626 		avail_idx += desc_count;
627 		if (avail_idx >= vq->size)
628 			avail_idx -= vq->size;
629 
630 		*nr_descs += desc_count;
631 		*num_buffers += 1;
632 	}
633 
634 	*nr_vec = vec_idx;
635 
636 	return 0;
637 }
638 
639 static __rte_always_inline int
640 copy_mbuf_to_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
641 			    struct rte_mbuf *m, struct buf_vector *buf_vec,
642 			    uint16_t nr_vec, uint16_t num_buffers)
643 {
644 	uint32_t vec_idx = 0;
645 	uint32_t mbuf_offset, mbuf_avail;
646 	uint32_t buf_offset, buf_avail;
647 	uint64_t buf_addr, buf_iova, buf_len;
648 	uint32_t cpy_len;
649 	uint64_t hdr_addr;
650 	struct rte_mbuf *hdr_mbuf;
651 	struct batch_copy_elem *batch_copy = vq->batch_copy_elems;
652 	struct virtio_net_hdr_mrg_rxbuf tmp_hdr, *hdr = NULL;
653 	int error = 0;
654 
655 	if (unlikely(m == NULL)) {
656 		error = -1;
657 		goto out;
658 	}
659 
660 	buf_addr = buf_vec[vec_idx].buf_addr;
661 	buf_iova = buf_vec[vec_idx].buf_iova;
662 	buf_len = buf_vec[vec_idx].buf_len;
663 
664 	if (nr_vec > 1)
665 		rte_prefetch0((void *)(uintptr_t)buf_vec[1].buf_addr);
666 
667 	if (unlikely(buf_len < dev->vhost_hlen && nr_vec <= 1)) {
668 		error = -1;
669 		goto out;
670 	}
671 
672 	hdr_mbuf = m;
673 	hdr_addr = buf_addr;
674 	if (unlikely(buf_len < dev->vhost_hlen))
675 		hdr = &tmp_hdr;
676 	else
677 		hdr = (struct virtio_net_hdr_mrg_rxbuf *)(uintptr_t)hdr_addr;
678 
679 	VHOST_LOG_DEBUG(VHOST_DATA, "(%d) RX: num merge buffers %d\n",
680 		dev->vid, num_buffers);
681 
682 	if (unlikely(buf_len < dev->vhost_hlen)) {
683 		buf_offset = dev->vhost_hlen - buf_len;
684 		vec_idx++;
685 		buf_addr = buf_vec[vec_idx].buf_addr;
686 		buf_iova = buf_vec[vec_idx].buf_iova;
687 		buf_len = buf_vec[vec_idx].buf_len;
688 		buf_avail = buf_len - buf_offset;
689 	} else {
690 		buf_offset = dev->vhost_hlen;
691 		buf_avail = buf_len - dev->vhost_hlen;
692 	}
693 
694 	mbuf_avail  = rte_pktmbuf_data_len(m);
695 	mbuf_offset = 0;
696 	while (mbuf_avail != 0 || m->next != NULL) {
697 		/* done with current buf, get the next one */
698 		if (buf_avail == 0) {
699 			vec_idx++;
700 			if (unlikely(vec_idx >= nr_vec)) {
701 				error = -1;
702 				goto out;
703 			}
704 
705 			buf_addr = buf_vec[vec_idx].buf_addr;
706 			buf_iova = buf_vec[vec_idx].buf_iova;
707 			buf_len = buf_vec[vec_idx].buf_len;
708 
709 			/* Prefetch next buffer address. */
710 			if (vec_idx + 1 < nr_vec)
711 				rte_prefetch0((void *)(uintptr_t)
712 						buf_vec[vec_idx + 1].buf_addr);
713 			buf_offset = 0;
714 			buf_avail  = buf_len;
715 		}
716 
717 		/* done with current mbuf, get the next one */
718 		if (mbuf_avail == 0) {
719 			m = m->next;
720 
721 			mbuf_offset = 0;
722 			mbuf_avail  = rte_pktmbuf_data_len(m);
723 		}
724 
725 		if (hdr_addr) {
726 			virtio_enqueue_offload(hdr_mbuf, &hdr->hdr);
727 			if (rxvq_is_mergeable(dev))
728 				ASSIGN_UNLESS_EQUAL(hdr->num_buffers,
729 						num_buffers);
730 
731 			if (unlikely(hdr == &tmp_hdr)) {
732 				uint64_t len;
733 				uint64_t remain = dev->vhost_hlen;
734 				uint64_t src = (uint64_t)(uintptr_t)hdr, dst;
735 				uint64_t iova = buf_vec[0].buf_iova;
736 				uint16_t hdr_vec_idx = 0;
737 
738 				while (remain) {
739 					len = RTE_MIN(remain,
740 						buf_vec[hdr_vec_idx].buf_len);
741 					dst = buf_vec[hdr_vec_idx].buf_addr;
742 					rte_memcpy((void *)(uintptr_t)dst,
743 							(void *)(uintptr_t)src,
744 							len);
745 
746 					PRINT_PACKET(dev, (uintptr_t)dst,
747 							(uint32_t)len, 0);
748 					vhost_log_cache_write(dev, vq,
749 							iova, len);
750 
751 					remain -= len;
752 					iova += len;
753 					src += len;
754 					hdr_vec_idx++;
755 				}
756 			} else {
757 				PRINT_PACKET(dev, (uintptr_t)hdr_addr,
758 						dev->vhost_hlen, 0);
759 				vhost_log_cache_write(dev, vq,
760 						buf_vec[0].buf_iova,
761 						dev->vhost_hlen);
762 			}
763 
764 			hdr_addr = 0;
765 		}
766 
767 		cpy_len = RTE_MIN(buf_avail, mbuf_avail);
768 
769 		if (likely(cpy_len > MAX_BATCH_LEN ||
770 					vq->batch_copy_nb_elems >= vq->size)) {
771 			rte_memcpy((void *)((uintptr_t)(buf_addr + buf_offset)),
772 				rte_pktmbuf_mtod_offset(m, void *, mbuf_offset),
773 				cpy_len);
774 			vhost_log_cache_write(dev, vq, buf_iova + buf_offset,
775 					cpy_len);
776 			PRINT_PACKET(dev, (uintptr_t)(buf_addr + buf_offset),
777 				cpy_len, 0);
778 		} else {
779 			batch_copy[vq->batch_copy_nb_elems].dst =
780 				(void *)((uintptr_t)(buf_addr + buf_offset));
781 			batch_copy[vq->batch_copy_nb_elems].src =
782 				rte_pktmbuf_mtod_offset(m, void *, mbuf_offset);
783 			batch_copy[vq->batch_copy_nb_elems].log_addr =
784 				buf_iova + buf_offset;
785 			batch_copy[vq->batch_copy_nb_elems].len = cpy_len;
786 			vq->batch_copy_nb_elems++;
787 		}
788 
789 		mbuf_avail  -= cpy_len;
790 		mbuf_offset += cpy_len;
791 		buf_avail  -= cpy_len;
792 		buf_offset += cpy_len;
793 	}
794 
795 out:
796 
797 	return error;
798 }
799 
800 static __rte_always_inline uint32_t
801 virtio_dev_rx_split(struct virtio_net *dev, struct vhost_virtqueue *vq,
802 	struct rte_mbuf **pkts, uint32_t count)
803 {
804 	uint32_t pkt_idx = 0;
805 	uint16_t num_buffers;
806 	struct buf_vector buf_vec[BUF_VECTOR_MAX];
807 	uint16_t avail_head;
808 
809 	rte_prefetch0(&vq->avail->ring[vq->last_avail_idx & (vq->size - 1)]);
810 	avail_head = *((volatile uint16_t *)&vq->avail->idx);
811 
812 	/*
813 	 * The ordering between avail index and
814 	 * desc reads needs to be enforced.
815 	 */
816 	rte_smp_rmb();
817 
818 	for (pkt_idx = 0; pkt_idx < count; pkt_idx++) {
819 		uint32_t pkt_len = pkts[pkt_idx]->pkt_len + dev->vhost_hlen;
820 		uint16_t nr_vec = 0;
821 
822 		if (unlikely(reserve_avail_buf_split(dev, vq,
823 						pkt_len, buf_vec, &num_buffers,
824 						avail_head, &nr_vec) < 0)) {
825 			VHOST_LOG_DEBUG(VHOST_DATA,
826 				"(%d) failed to get enough desc from vring\n",
827 				dev->vid);
828 			vq->shadow_used_idx -= num_buffers;
829 			break;
830 		}
831 
832 		rte_prefetch0((void *)(uintptr_t)buf_vec[0].buf_addr);
833 
834 		VHOST_LOG_DEBUG(VHOST_DATA, "(%d) current index %d | end index %d\n",
835 			dev->vid, vq->last_avail_idx,
836 			vq->last_avail_idx + num_buffers);
837 
838 		if (copy_mbuf_to_desc(dev, vq, pkts[pkt_idx],
839 						buf_vec, nr_vec,
840 						num_buffers) < 0) {
841 			vq->shadow_used_idx -= num_buffers;
842 			break;
843 		}
844 
845 		vq->last_avail_idx += num_buffers;
846 	}
847 
848 	do_data_copy_enqueue(dev, vq);
849 
850 	if (likely(vq->shadow_used_idx)) {
851 		flush_shadow_used_ring_split(dev, vq);
852 		vhost_vring_call_split(dev, vq);
853 	}
854 
855 	return pkt_idx;
856 }
857 
858 static __rte_always_inline uint32_t
859 virtio_dev_rx_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,
860 	struct rte_mbuf **pkts, uint32_t count)
861 {
862 	uint32_t pkt_idx = 0;
863 	uint16_t num_buffers;
864 	struct buf_vector buf_vec[BUF_VECTOR_MAX];
865 
866 	for (pkt_idx = 0; pkt_idx < count; pkt_idx++) {
867 		uint32_t pkt_len = pkts[pkt_idx]->pkt_len + dev->vhost_hlen;
868 		uint16_t nr_vec = 0;
869 		uint16_t nr_descs = 0;
870 
871 		if (unlikely(reserve_avail_buf_packed(dev, vq,
872 						pkt_len, buf_vec, &nr_vec,
873 						&num_buffers, &nr_descs) < 0)) {
874 			VHOST_LOG_DEBUG(VHOST_DATA,
875 				"(%d) failed to get enough desc from vring\n",
876 				dev->vid);
877 			vq->shadow_used_idx -= num_buffers;
878 			break;
879 		}
880 
881 		rte_prefetch0((void *)(uintptr_t)buf_vec[0].buf_addr);
882 
883 		VHOST_LOG_DEBUG(VHOST_DATA, "(%d) current index %d | end index %d\n",
884 			dev->vid, vq->last_avail_idx,
885 			vq->last_avail_idx + num_buffers);
886 
887 		if (copy_mbuf_to_desc(dev, vq, pkts[pkt_idx],
888 						buf_vec, nr_vec,
889 						num_buffers) < 0) {
890 			vq->shadow_used_idx -= num_buffers;
891 			break;
892 		}
893 
894 		vq->last_avail_idx += nr_descs;
895 		if (vq->last_avail_idx >= vq->size) {
896 			vq->last_avail_idx -= vq->size;
897 			vq->avail_wrap_counter ^= 1;
898 		}
899 	}
900 
901 	do_data_copy_enqueue(dev, vq);
902 
903 	if (likely(vq->shadow_used_idx)) {
904 		flush_shadow_used_ring_packed(dev, vq);
905 		vhost_vring_call_packed(dev, vq);
906 	}
907 
908 	return pkt_idx;
909 }
910 
911 static __rte_always_inline uint32_t
912 virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
913 	struct rte_mbuf **pkts, uint32_t count)
914 {
915 	struct vhost_virtqueue *vq;
916 	uint32_t nb_tx = 0;
917 
918 	VHOST_LOG_DEBUG(VHOST_DATA, "(%d) %s\n", dev->vid, __func__);
919 	if (unlikely(!is_valid_virt_queue_idx(queue_id, 0, dev->nr_vring))) {
920 		RTE_LOG(ERR, VHOST_DATA, "(%d) %s: invalid virtqueue idx %d.\n",
921 			dev->vid, __func__, queue_id);
922 		return 0;
923 	}
924 
925 	vq = dev->virtqueue[queue_id];
926 
927 	rte_spinlock_lock(&vq->access_lock);
928 
929 	if (unlikely(vq->enabled == 0))
930 		goto out_access_unlock;
931 
932 	if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))
933 		vhost_user_iotlb_rd_lock(vq);
934 
935 	if (unlikely(vq->access_ok == 0))
936 		if (unlikely(vring_translate(dev, vq) < 0))
937 			goto out;
938 
939 	count = RTE_MIN((uint32_t)MAX_PKT_BURST, count);
940 	if (count == 0)
941 		goto out;
942 
943 	if (vq_is_packed(dev))
944 		nb_tx = virtio_dev_rx_packed(dev, vq, pkts, count);
945 	else
946 		nb_tx = virtio_dev_rx_split(dev, vq, pkts, count);
947 
948 out:
949 	if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))
950 		vhost_user_iotlb_rd_unlock(vq);
951 
952 out_access_unlock:
953 	rte_spinlock_unlock(&vq->access_lock);
954 
955 	return nb_tx;
956 }
957 
958 uint16_t
959 rte_vhost_enqueue_burst(int vid, uint16_t queue_id,
960 	struct rte_mbuf **pkts, uint16_t count)
961 {
962 	struct virtio_net *dev = get_device(vid);
963 
964 	if (!dev)
965 		return 0;
966 
967 	if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
968 		RTE_LOG(ERR, VHOST_DATA,
969 			"(%d) %s: built-in vhost net backend is disabled.\n",
970 			dev->vid, __func__);
971 		return 0;
972 	}
973 
974 	return virtio_dev_rx(dev, queue_id, pkts, count);
975 }
976 
977 static inline bool
978 virtio_net_with_host_offload(struct virtio_net *dev)
979 {
980 	if (dev->features &
981 			((1ULL << VIRTIO_NET_F_CSUM) |
982 			 (1ULL << VIRTIO_NET_F_HOST_ECN) |
983 			 (1ULL << VIRTIO_NET_F_HOST_TSO4) |
984 			 (1ULL << VIRTIO_NET_F_HOST_TSO6) |
985 			 (1ULL << VIRTIO_NET_F_HOST_UFO)))
986 		return true;
987 
988 	return false;
989 }
990 
991 static void
992 parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr)
993 {
994 	struct ipv4_hdr *ipv4_hdr;
995 	struct ipv6_hdr *ipv6_hdr;
996 	void *l3_hdr = NULL;
997 	struct ether_hdr *eth_hdr;
998 	uint16_t ethertype;
999 
1000 	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
1001 
1002 	m->l2_len = sizeof(struct ether_hdr);
1003 	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
1004 
1005 	if (ethertype == ETHER_TYPE_VLAN) {
1006 		struct vlan_hdr *vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
1007 
1008 		m->l2_len += sizeof(struct vlan_hdr);
1009 		ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto);
1010 	}
1011 
1012 	l3_hdr = (char *)eth_hdr + m->l2_len;
1013 
1014 	switch (ethertype) {
1015 	case ETHER_TYPE_IPv4:
1016 		ipv4_hdr = l3_hdr;
1017 		*l4_proto = ipv4_hdr->next_proto_id;
1018 		m->l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4;
1019 		*l4_hdr = (char *)l3_hdr + m->l3_len;
1020 		m->ol_flags |= PKT_TX_IPV4;
1021 		break;
1022 	case ETHER_TYPE_IPv6:
1023 		ipv6_hdr = l3_hdr;
1024 		*l4_proto = ipv6_hdr->proto;
1025 		m->l3_len = sizeof(struct ipv6_hdr);
1026 		*l4_hdr = (char *)l3_hdr + m->l3_len;
1027 		m->ol_flags |= PKT_TX_IPV6;
1028 		break;
1029 	default:
1030 		m->l3_len = 0;
1031 		*l4_proto = 0;
1032 		*l4_hdr = NULL;
1033 		break;
1034 	}
1035 }
1036 
1037 static __rte_always_inline void
1038 vhost_dequeue_offload(struct virtio_net_hdr *hdr, struct rte_mbuf *m)
1039 {
1040 	uint16_t l4_proto = 0;
1041 	void *l4_hdr = NULL;
1042 	struct tcp_hdr *tcp_hdr = NULL;
1043 
1044 	if (hdr->flags == 0 && hdr->gso_type == VIRTIO_NET_HDR_GSO_NONE)
1045 		return;
1046 
1047 	parse_ethernet(m, &l4_proto, &l4_hdr);
1048 	if (hdr->flags == VIRTIO_NET_HDR_F_NEEDS_CSUM) {
1049 		if (hdr->csum_start == (m->l2_len + m->l3_len)) {
1050 			switch (hdr->csum_offset) {
1051 			case (offsetof(struct tcp_hdr, cksum)):
1052 				if (l4_proto == IPPROTO_TCP)
1053 					m->ol_flags |= PKT_TX_TCP_CKSUM;
1054 				break;
1055 			case (offsetof(struct udp_hdr, dgram_cksum)):
1056 				if (l4_proto == IPPROTO_UDP)
1057 					m->ol_flags |= PKT_TX_UDP_CKSUM;
1058 				break;
1059 			case (offsetof(struct sctp_hdr, cksum)):
1060 				if (l4_proto == IPPROTO_SCTP)
1061 					m->ol_flags |= PKT_TX_SCTP_CKSUM;
1062 				break;
1063 			default:
1064 				break;
1065 			}
1066 		}
1067 	}
1068 
1069 	if (l4_hdr && hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
1070 		switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
1071 		case VIRTIO_NET_HDR_GSO_TCPV4:
1072 		case VIRTIO_NET_HDR_GSO_TCPV6:
1073 			tcp_hdr = l4_hdr;
1074 			m->ol_flags |= PKT_TX_TCP_SEG;
1075 			m->tso_segsz = hdr->gso_size;
1076 			m->l4_len = (tcp_hdr->data_off & 0xf0) >> 2;
1077 			break;
1078 		case VIRTIO_NET_HDR_GSO_UDP:
1079 			m->ol_flags |= PKT_TX_UDP_SEG;
1080 			m->tso_segsz = hdr->gso_size;
1081 			m->l4_len = sizeof(struct udp_hdr);
1082 			break;
1083 		default:
1084 			RTE_LOG(WARNING, VHOST_DATA,
1085 				"unsupported gso type %u.\n", hdr->gso_type);
1086 			break;
1087 		}
1088 	}
1089 }
1090 
1091 static __rte_always_inline int
1092 copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq,
1093 		  struct buf_vector *buf_vec, uint16_t nr_vec,
1094 		  struct rte_mbuf *m, struct rte_mempool *mbuf_pool)
1095 {
1096 	uint32_t buf_avail, buf_offset;
1097 	uint64_t buf_addr, buf_iova, buf_len;
1098 	uint32_t mbuf_avail, mbuf_offset;
1099 	uint32_t cpy_len;
1100 	struct rte_mbuf *cur = m, *prev = m;
1101 	struct virtio_net_hdr tmp_hdr;
1102 	struct virtio_net_hdr *hdr = NULL;
1103 	/* A counter to avoid desc dead loop chain */
1104 	uint16_t vec_idx = 0;
1105 	struct batch_copy_elem *batch_copy = vq->batch_copy_elems;
1106 	int error = 0;
1107 
1108 	buf_addr = buf_vec[vec_idx].buf_addr;
1109 	buf_iova = buf_vec[vec_idx].buf_iova;
1110 	buf_len = buf_vec[vec_idx].buf_len;
1111 
1112 	if (unlikely(buf_len < dev->vhost_hlen && nr_vec <= 1)) {
1113 		error = -1;
1114 		goto out;
1115 	}
1116 
1117 	if (likely(nr_vec > 1))
1118 		rte_prefetch0((void *)(uintptr_t)buf_vec[1].buf_addr);
1119 
1120 	if (virtio_net_with_host_offload(dev)) {
1121 		if (unlikely(buf_len < sizeof(struct virtio_net_hdr))) {
1122 			uint64_t len;
1123 			uint64_t remain = sizeof(struct virtio_net_hdr);
1124 			uint64_t src;
1125 			uint64_t dst = (uint64_t)(uintptr_t)&tmp_hdr;
1126 			uint16_t hdr_vec_idx = 0;
1127 
1128 			/*
1129 			 * No luck, the virtio-net header doesn't fit
1130 			 * in a contiguous virtual area.
1131 			 */
1132 			while (remain) {
1133 				len = RTE_MIN(remain,
1134 					buf_vec[hdr_vec_idx].buf_len);
1135 				src = buf_vec[hdr_vec_idx].buf_addr;
1136 				rte_memcpy((void *)(uintptr_t)dst,
1137 						   (void *)(uintptr_t)src, len);
1138 
1139 				remain -= len;
1140 				dst += len;
1141 				hdr_vec_idx++;
1142 			}
1143 
1144 			hdr = &tmp_hdr;
1145 		} else {
1146 			hdr = (struct virtio_net_hdr *)((uintptr_t)buf_addr);
1147 			rte_prefetch0(hdr);
1148 		}
1149 	}
1150 
1151 	/*
1152 	 * A virtio driver normally uses at least 2 desc buffers
1153 	 * for Tx: the first for storing the header, and others
1154 	 * for storing the data.
1155 	 */
1156 	if (unlikely(buf_len < dev->vhost_hlen)) {
1157 		buf_offset = dev->vhost_hlen - buf_len;
1158 		vec_idx++;
1159 		buf_addr = buf_vec[vec_idx].buf_addr;
1160 		buf_iova = buf_vec[vec_idx].buf_iova;
1161 		buf_len = buf_vec[vec_idx].buf_len;
1162 		buf_avail  = buf_len - buf_offset;
1163 	} else if (buf_len == dev->vhost_hlen) {
1164 		if (unlikely(++vec_idx >= nr_vec))
1165 			goto out;
1166 		buf_addr = buf_vec[vec_idx].buf_addr;
1167 		buf_iova = buf_vec[vec_idx].buf_iova;
1168 		buf_len = buf_vec[vec_idx].buf_len;
1169 
1170 		buf_offset = 0;
1171 		buf_avail = buf_len;
1172 	} else {
1173 		buf_offset = dev->vhost_hlen;
1174 		buf_avail = buf_vec[vec_idx].buf_len - dev->vhost_hlen;
1175 	}
1176 
1177 	rte_prefetch0((void *)(uintptr_t)
1178 			(buf_addr + buf_offset));
1179 
1180 	PRINT_PACKET(dev,
1181 			(uintptr_t)(buf_addr + buf_offset),
1182 			(uint32_t)buf_avail, 0);
1183 
1184 	mbuf_offset = 0;
1185 	mbuf_avail  = m->buf_len - RTE_PKTMBUF_HEADROOM;
1186 	while (1) {
1187 		uint64_t hpa;
1188 
1189 		cpy_len = RTE_MIN(buf_avail, mbuf_avail);
1190 
1191 		/*
1192 		 * A desc buf might across two host physical pages that are
1193 		 * not continuous. In such case (gpa_to_hpa returns 0), data
1194 		 * will be copied even though zero copy is enabled.
1195 		 */
1196 		if (unlikely(dev->dequeue_zero_copy && (hpa = gpa_to_hpa(dev,
1197 					buf_iova + buf_offset, cpy_len)))) {
1198 			cur->data_len = cpy_len;
1199 			cur->data_off = 0;
1200 			cur->buf_addr =
1201 				(void *)(uintptr_t)(buf_addr + buf_offset);
1202 			cur->buf_iova = hpa;
1203 
1204 			/*
1205 			 * In zero copy mode, one mbuf can only reference data
1206 			 * for one or partial of one desc buff.
1207 			 */
1208 			mbuf_avail = cpy_len;
1209 		} else {
1210 			if (likely(cpy_len > MAX_BATCH_LEN ||
1211 				   vq->batch_copy_nb_elems >= vq->size ||
1212 				   (hdr && cur == m))) {
1213 				rte_memcpy(rte_pktmbuf_mtod_offset(cur, void *,
1214 								   mbuf_offset),
1215 					   (void *)((uintptr_t)(buf_addr +
1216 							   buf_offset)),
1217 					   cpy_len);
1218 			} else {
1219 				batch_copy[vq->batch_copy_nb_elems].dst =
1220 					rte_pktmbuf_mtod_offset(cur, void *,
1221 								mbuf_offset);
1222 				batch_copy[vq->batch_copy_nb_elems].src =
1223 					(void *)((uintptr_t)(buf_addr +
1224 								buf_offset));
1225 				batch_copy[vq->batch_copy_nb_elems].len =
1226 					cpy_len;
1227 				vq->batch_copy_nb_elems++;
1228 			}
1229 		}
1230 
1231 		mbuf_avail  -= cpy_len;
1232 		mbuf_offset += cpy_len;
1233 		buf_avail -= cpy_len;
1234 		buf_offset += cpy_len;
1235 
1236 		/* This buf reaches to its end, get the next one */
1237 		if (buf_avail == 0) {
1238 			if (++vec_idx >= nr_vec)
1239 				break;
1240 
1241 			buf_addr = buf_vec[vec_idx].buf_addr;
1242 			buf_iova = buf_vec[vec_idx].buf_iova;
1243 			buf_len = buf_vec[vec_idx].buf_len;
1244 
1245 			/*
1246 			 * Prefecth desc n + 1 buffer while
1247 			 * desc n buffer is processed.
1248 			 */
1249 			if (vec_idx + 1 < nr_vec)
1250 				rte_prefetch0((void *)(uintptr_t)
1251 						buf_vec[vec_idx + 1].buf_addr);
1252 
1253 			buf_offset = 0;
1254 			buf_avail  = buf_len;
1255 
1256 			PRINT_PACKET(dev, (uintptr_t)buf_addr,
1257 					(uint32_t)buf_avail, 0);
1258 		}
1259 
1260 		/*
1261 		 * This mbuf reaches to its end, get a new one
1262 		 * to hold more data.
1263 		 */
1264 		if (mbuf_avail == 0) {
1265 			cur = rte_pktmbuf_alloc(mbuf_pool);
1266 			if (unlikely(cur == NULL)) {
1267 				RTE_LOG(ERR, VHOST_DATA, "Failed to "
1268 					"allocate memory for mbuf.\n");
1269 				error = -1;
1270 				goto out;
1271 			}
1272 			if (unlikely(dev->dequeue_zero_copy))
1273 				rte_mbuf_refcnt_update(cur, 1);
1274 
1275 			prev->next = cur;
1276 			prev->data_len = mbuf_offset;
1277 			m->nb_segs += 1;
1278 			m->pkt_len += mbuf_offset;
1279 			prev = cur;
1280 
1281 			mbuf_offset = 0;
1282 			mbuf_avail  = cur->buf_len - RTE_PKTMBUF_HEADROOM;
1283 		}
1284 	}
1285 
1286 	prev->data_len = mbuf_offset;
1287 	m->pkt_len    += mbuf_offset;
1288 
1289 	if (hdr)
1290 		vhost_dequeue_offload(hdr, m);
1291 
1292 out:
1293 
1294 	return error;
1295 }
1296 
1297 static __rte_always_inline struct zcopy_mbuf *
1298 get_zmbuf(struct vhost_virtqueue *vq)
1299 {
1300 	uint16_t i;
1301 	uint16_t last;
1302 	int tries = 0;
1303 
1304 	/* search [last_zmbuf_idx, zmbuf_size) */
1305 	i = vq->last_zmbuf_idx;
1306 	last = vq->zmbuf_size;
1307 
1308 again:
1309 	for (; i < last; i++) {
1310 		if (vq->zmbufs[i].in_use == 0) {
1311 			vq->last_zmbuf_idx = i + 1;
1312 			vq->zmbufs[i].in_use = 1;
1313 			return &vq->zmbufs[i];
1314 		}
1315 	}
1316 
1317 	tries++;
1318 	if (tries == 1) {
1319 		/* search [0, last_zmbuf_idx) */
1320 		i = 0;
1321 		last = vq->last_zmbuf_idx;
1322 		goto again;
1323 	}
1324 
1325 	return NULL;
1326 }
1327 
1328 static __rte_always_inline uint16_t
1329 virtio_dev_tx_split(struct virtio_net *dev, struct vhost_virtqueue *vq,
1330 	struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
1331 {
1332 	uint16_t i;
1333 	uint16_t free_entries;
1334 
1335 	if (unlikely(dev->dequeue_zero_copy)) {
1336 		struct zcopy_mbuf *zmbuf, *next;
1337 
1338 		for (zmbuf = TAILQ_FIRST(&vq->zmbuf_list);
1339 		     zmbuf != NULL; zmbuf = next) {
1340 			next = TAILQ_NEXT(zmbuf, next);
1341 
1342 			if (mbuf_is_consumed(zmbuf->mbuf)) {
1343 				update_shadow_used_ring_split(vq,
1344 						zmbuf->desc_idx, 0);
1345 				TAILQ_REMOVE(&vq->zmbuf_list, zmbuf, next);
1346 				restore_mbuf(zmbuf->mbuf);
1347 				rte_pktmbuf_free(zmbuf->mbuf);
1348 				put_zmbuf(zmbuf);
1349 				vq->nr_zmbuf -= 1;
1350 			}
1351 		}
1352 
1353 		if (likely(vq->shadow_used_idx)) {
1354 			flush_shadow_used_ring_split(dev, vq);
1355 			vhost_vring_call_split(dev, vq);
1356 		}
1357 	}
1358 
1359 	rte_prefetch0(&vq->avail->ring[vq->last_avail_idx & (vq->size - 1)]);
1360 
1361 	free_entries = *((volatile uint16_t *)&vq->avail->idx) -
1362 			vq->last_avail_idx;
1363 	if (free_entries == 0)
1364 		return 0;
1365 
1366 	/*
1367 	 * The ordering between avail index and
1368 	 * desc reads needs to be enforced.
1369 	 */
1370 	rte_smp_rmb();
1371 
1372 	VHOST_LOG_DEBUG(VHOST_DATA, "(%d) %s\n", dev->vid, __func__);
1373 
1374 	count = RTE_MIN(count, MAX_PKT_BURST);
1375 	count = RTE_MIN(count, free_entries);
1376 	VHOST_LOG_DEBUG(VHOST_DATA, "(%d) about to dequeue %u buffers\n",
1377 			dev->vid, count);
1378 
1379 	for (i = 0; i < count; i++) {
1380 		struct buf_vector buf_vec[BUF_VECTOR_MAX];
1381 		uint16_t head_idx;
1382 		uint32_t dummy_len;
1383 		uint16_t nr_vec = 0;
1384 		int err;
1385 
1386 		if (unlikely(fill_vec_buf_split(dev, vq,
1387 						vq->last_avail_idx + i,
1388 						&nr_vec, buf_vec,
1389 						&head_idx, &dummy_len,
1390 						VHOST_ACCESS_RO) < 0))
1391 			break;
1392 
1393 		if (likely(dev->dequeue_zero_copy == 0))
1394 			update_shadow_used_ring_split(vq, head_idx, 0);
1395 
1396 		rte_prefetch0((void *)(uintptr_t)buf_vec[0].buf_addr);
1397 
1398 		pkts[i] = rte_pktmbuf_alloc(mbuf_pool);
1399 		if (unlikely(pkts[i] == NULL)) {
1400 			RTE_LOG(ERR, VHOST_DATA,
1401 				"Failed to allocate memory for mbuf.\n");
1402 			break;
1403 		}
1404 
1405 		err = copy_desc_to_mbuf(dev, vq, buf_vec, nr_vec, pkts[i],
1406 				mbuf_pool);
1407 		if (unlikely(err)) {
1408 			rte_pktmbuf_free(pkts[i]);
1409 			break;
1410 		}
1411 
1412 		if (unlikely(dev->dequeue_zero_copy)) {
1413 			struct zcopy_mbuf *zmbuf;
1414 
1415 			zmbuf = get_zmbuf(vq);
1416 			if (!zmbuf) {
1417 				rte_pktmbuf_free(pkts[i]);
1418 				break;
1419 			}
1420 			zmbuf->mbuf = pkts[i];
1421 			zmbuf->desc_idx = head_idx;
1422 
1423 			/*
1424 			 * Pin lock the mbuf; we will check later to see
1425 			 * whether the mbuf is freed (when we are the last
1426 			 * user) or not. If that's the case, we then could
1427 			 * update the used ring safely.
1428 			 */
1429 			rte_mbuf_refcnt_update(pkts[i], 1);
1430 
1431 			vq->nr_zmbuf += 1;
1432 			TAILQ_INSERT_TAIL(&vq->zmbuf_list, zmbuf, next);
1433 		}
1434 	}
1435 	vq->last_avail_idx += i;
1436 
1437 	if (likely(dev->dequeue_zero_copy == 0)) {
1438 		do_data_copy_dequeue(vq);
1439 		if (unlikely(i < count))
1440 			vq->shadow_used_idx = i;
1441 		if (likely(vq->shadow_used_idx)) {
1442 			flush_shadow_used_ring_split(dev, vq);
1443 			vhost_vring_call_split(dev, vq);
1444 		}
1445 	}
1446 
1447 	return i;
1448 }
1449 
1450 static __rte_always_inline uint16_t
1451 virtio_dev_tx_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,
1452 	struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
1453 {
1454 	uint16_t i;
1455 
1456 	rte_prefetch0(&vq->desc_packed[vq->last_avail_idx]);
1457 
1458 	if (unlikely(dev->dequeue_zero_copy)) {
1459 		struct zcopy_mbuf *zmbuf, *next;
1460 
1461 		for (zmbuf = TAILQ_FIRST(&vq->zmbuf_list);
1462 		     zmbuf != NULL; zmbuf = next) {
1463 			next = TAILQ_NEXT(zmbuf, next);
1464 
1465 			if (mbuf_is_consumed(zmbuf->mbuf)) {
1466 				update_shadow_used_ring_packed(vq,
1467 						zmbuf->desc_idx,
1468 						0,
1469 						zmbuf->desc_count);
1470 
1471 				TAILQ_REMOVE(&vq->zmbuf_list, zmbuf, next);
1472 				restore_mbuf(zmbuf->mbuf);
1473 				rte_pktmbuf_free(zmbuf->mbuf);
1474 				put_zmbuf(zmbuf);
1475 				vq->nr_zmbuf -= 1;
1476 			}
1477 		}
1478 
1479 		if (likely(vq->shadow_used_idx)) {
1480 			flush_shadow_used_ring_packed(dev, vq);
1481 			vhost_vring_call_packed(dev, vq);
1482 		}
1483 	}
1484 
1485 	VHOST_LOG_DEBUG(VHOST_DATA, "(%d) %s\n", dev->vid, __func__);
1486 
1487 	count = RTE_MIN(count, MAX_PKT_BURST);
1488 	VHOST_LOG_DEBUG(VHOST_DATA, "(%d) about to dequeue %u buffers\n",
1489 			dev->vid, count);
1490 
1491 	for (i = 0; i < count; i++) {
1492 		struct buf_vector buf_vec[BUF_VECTOR_MAX];
1493 		uint16_t buf_id;
1494 		uint32_t dummy_len;
1495 		uint16_t desc_count, nr_vec = 0;
1496 		int err;
1497 
1498 		if (unlikely(fill_vec_buf_packed(dev, vq,
1499 						vq->last_avail_idx, &desc_count,
1500 						buf_vec, &nr_vec,
1501 						&buf_id, &dummy_len,
1502 						VHOST_ACCESS_RO) < 0))
1503 			break;
1504 
1505 		if (likely(dev->dequeue_zero_copy == 0))
1506 			update_shadow_used_ring_packed(vq, buf_id, 0,
1507 					desc_count);
1508 
1509 		rte_prefetch0((void *)(uintptr_t)buf_vec[0].buf_addr);
1510 
1511 		pkts[i] = rte_pktmbuf_alloc(mbuf_pool);
1512 		if (unlikely(pkts[i] == NULL)) {
1513 			RTE_LOG(ERR, VHOST_DATA,
1514 				"Failed to allocate memory for mbuf.\n");
1515 			break;
1516 		}
1517 
1518 		err = copy_desc_to_mbuf(dev, vq, buf_vec, nr_vec, pkts[i],
1519 				mbuf_pool);
1520 		if (unlikely(err)) {
1521 			rte_pktmbuf_free(pkts[i]);
1522 			break;
1523 		}
1524 
1525 		if (unlikely(dev->dequeue_zero_copy)) {
1526 			struct zcopy_mbuf *zmbuf;
1527 
1528 			zmbuf = get_zmbuf(vq);
1529 			if (!zmbuf) {
1530 				rte_pktmbuf_free(pkts[i]);
1531 				break;
1532 			}
1533 			zmbuf->mbuf = pkts[i];
1534 			zmbuf->desc_idx = buf_id;
1535 			zmbuf->desc_count = desc_count;
1536 
1537 			/*
1538 			 * Pin lock the mbuf; we will check later to see
1539 			 * whether the mbuf is freed (when we are the last
1540 			 * user) or not. If that's the case, we then could
1541 			 * update the used ring safely.
1542 			 */
1543 			rte_mbuf_refcnt_update(pkts[i], 1);
1544 
1545 			vq->nr_zmbuf += 1;
1546 			TAILQ_INSERT_TAIL(&vq->zmbuf_list, zmbuf, next);
1547 		}
1548 
1549 		vq->last_avail_idx += desc_count;
1550 		if (vq->last_avail_idx >= vq->size) {
1551 			vq->last_avail_idx -= vq->size;
1552 			vq->avail_wrap_counter ^= 1;
1553 		}
1554 	}
1555 
1556 	if (likely(dev->dequeue_zero_copy == 0)) {
1557 		do_data_copy_dequeue(vq);
1558 		if (unlikely(i < count))
1559 			vq->shadow_used_idx = i;
1560 		if (likely(vq->shadow_used_idx)) {
1561 			flush_shadow_used_ring_packed(dev, vq);
1562 			vhost_vring_call_packed(dev, vq);
1563 		}
1564 	}
1565 
1566 	return i;
1567 }
1568 
1569 uint16_t
1570 rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
1571 	struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
1572 {
1573 	struct virtio_net *dev;
1574 	struct rte_mbuf *rarp_mbuf = NULL;
1575 	struct vhost_virtqueue *vq;
1576 
1577 	dev = get_device(vid);
1578 	if (!dev)
1579 		return 0;
1580 
1581 	if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
1582 		RTE_LOG(ERR, VHOST_DATA,
1583 			"(%d) %s: built-in vhost net backend is disabled.\n",
1584 			dev->vid, __func__);
1585 		return 0;
1586 	}
1587 
1588 	if (unlikely(!is_valid_virt_queue_idx(queue_id, 1, dev->nr_vring))) {
1589 		RTE_LOG(ERR, VHOST_DATA, "(%d) %s: invalid virtqueue idx %d.\n",
1590 			dev->vid, __func__, queue_id);
1591 		return 0;
1592 	}
1593 
1594 	vq = dev->virtqueue[queue_id];
1595 
1596 	if (unlikely(rte_spinlock_trylock(&vq->access_lock) == 0))
1597 		return 0;
1598 
1599 	if (unlikely(vq->enabled == 0)) {
1600 		count = 0;
1601 		goto out_access_unlock;
1602 	}
1603 
1604 	if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))
1605 		vhost_user_iotlb_rd_lock(vq);
1606 
1607 	if (unlikely(vq->access_ok == 0))
1608 		if (unlikely(vring_translate(dev, vq) < 0)) {
1609 			count = 0;
1610 			goto out;
1611 		}
1612 
1613 	/*
1614 	 * Construct a RARP broadcast packet, and inject it to the "pkts"
1615 	 * array, to looks like that guest actually send such packet.
1616 	 *
1617 	 * Check user_send_rarp() for more information.
1618 	 *
1619 	 * broadcast_rarp shares a cacheline in the virtio_net structure
1620 	 * with some fields that are accessed during enqueue and
1621 	 * rte_atomic16_cmpset() causes a write if using cmpxchg. This could
1622 	 * result in false sharing between enqueue and dequeue.
1623 	 *
1624 	 * Prevent unnecessary false sharing by reading broadcast_rarp first
1625 	 * and only performing cmpset if the read indicates it is likely to
1626 	 * be set.
1627 	 */
1628 	if (unlikely(rte_atomic16_read(&dev->broadcast_rarp) &&
1629 			rte_atomic16_cmpset((volatile uint16_t *)
1630 				&dev->broadcast_rarp.cnt, 1, 0))) {
1631 
1632 		rarp_mbuf = rte_net_make_rarp_packet(mbuf_pool, &dev->mac);
1633 		if (rarp_mbuf == NULL) {
1634 			RTE_LOG(ERR, VHOST_DATA,
1635 				"Failed to make RARP packet.\n");
1636 			count = 0;
1637 			goto out;
1638 		}
1639 		count -= 1;
1640 	}
1641 
1642 	if (vq_is_packed(dev))
1643 		count = virtio_dev_tx_packed(dev, vq, mbuf_pool, pkts, count);
1644 	else
1645 		count = virtio_dev_tx_split(dev, vq, mbuf_pool, pkts, count);
1646 
1647 out:
1648 	if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))
1649 		vhost_user_iotlb_rd_unlock(vq);
1650 
1651 out_access_unlock:
1652 	rte_spinlock_unlock(&vq->access_lock);
1653 
1654 	if (unlikely(rarp_mbuf != NULL)) {
1655 		/*
1656 		 * Inject it to the head of "pkts" array, so that switch's mac
1657 		 * learning table will get updated first.
1658 		 */
1659 		memmove(&pkts[1], pkts, count * sizeof(struct rte_mbuf *));
1660 		pkts[0] = rarp_mbuf;
1661 		count += 1;
1662 	}
1663 
1664 	return count;
1665 }
1666