| 450 | } |
| 451 | |
| 452 | static uint16_t |
| 453 | eth_vhost_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) |
| 454 | { |
| 455 | struct vhost_queue *r = q; |
| 456 | uint16_t i, nb_tx = 0; |
| 457 | uint16_t nb_send = 0; |
| 458 | uint64_t nb_bytes = 0; |
| 459 | uint64_t nb_missed = 0; |
| 460 | |
| 461 | if (unlikely(rte_atomic32_read(&r->allow_queuing) == 0)) |
| 462 | return 0; |
| 463 | |
| 464 | rte_atomic32_set(&r->while_queuing, 1); |
| 465 | |
| 466 | if (unlikely(rte_atomic32_read(&r->allow_queuing) == 0)) |
| 467 | goto out; |
| 468 | |
| 469 | for (i = 0; i < nb_bufs; i++) { |
| 470 | struct rte_mbuf *m = bufs[i]; |
| 471 | |
| 472 | /* Do VLAN tag insertion */ |
| 473 | if (m->ol_flags & RTE_MBUF_F_TX_VLAN) { |
| 474 | int error = rte_vlan_insert(&m); |
| 475 | if (unlikely(error)) { |
| 476 | rte_pktmbuf_free(m); |
| 477 | continue; |
| 478 | } |
| 479 | } |
| 480 | |
| 481 | if (r->internal->tx_sw_csum) |
| 482 | vhost_dev_tx_sw_csum(m); |
| 483 | |
| 484 | |
| 485 | bufs[nb_send] = m; |
| 486 | ++nb_send; |
| 487 | } |
| 488 | |
| 489 | /* Enqueue packets to guest RX queue */ |
| 490 | while (nb_send) { |
| 491 | uint16_t nb_pkts; |
| 492 | uint16_t num = (uint16_t)RTE_MIN(nb_send, |
| 493 | VHOST_MAX_PKT_BURST); |
| 494 | |
| 495 | nb_pkts = rte_vhost_enqueue_burst(r->vid, r->virtqueue_id, |
| 496 | &bufs[nb_tx], num); |
| 497 | |
| 498 | nb_tx += nb_pkts; |
| 499 | nb_send -= nb_pkts; |
| 500 | if (nb_pkts < num) |
| 501 | break; |
| 502 | } |
| 503 | |
| 504 | for (i = 0; likely(i < nb_tx); i++) |
| 505 | nb_bytes += bufs[i]->pkt_len; |
| 506 | |
| 507 | nb_missed = nb_bufs - nb_tx; |
| 508 | |
| 509 | r->stats.pkts += nb_tx; |
nothing calls this directly
no test coverage detected