| 3718 | } |
| 3719 | |
| 3720 | static __rte_always_inline uint16_t |
| 3721 | virtio_dev_tx_async_split(struct virtio_net *dev, struct vhost_virtqueue *vq, |
| 3722 | struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count, |
| 3723 | int16_t dma_id, uint16_t vchan_id, bool legacy_ol_flags) |
| 3724 | __rte_shared_locks_required(&vq->access_lock) |
| 3725 | __rte_shared_locks_required(&vq->iotlb_lock) |
| 3726 | { |
| 3727 | static bool allocerr_warned; |
| 3728 | bool dropped = false; |
| 3729 | uint16_t avail_entries; |
| 3730 | uint16_t pkt_idx, slot_idx = 0; |
| 3731 | uint16_t nr_done_pkts = 0; |
| 3732 | uint16_t pkt_err = 0; |
| 3733 | uint16_t n_xfer; |
| 3734 | struct vhost_async *async = vq->async; |
| 3735 | struct async_inflight_info *pkts_info = async->pkts_info; |
| 3736 | struct rte_mbuf *pkts_prealloc[MAX_PKT_BURST]; |
| 3737 | uint16_t pkts_size = count; |
| 3738 | |
| 3739 | /** |
| 3740 | * The ordering between avail index and |
| 3741 | * desc reads needs to be enforced. |
| 3742 | */ |
| 3743 | avail_entries = rte_atomic_load_explicit((unsigned short __rte_atomic *)&vq->avail->idx, |
| 3744 | rte_memory_order_acquire) - vq->last_avail_idx; |
| 3745 | if (avail_entries == 0) |
| 3746 | goto out; |
| 3747 | |
| 3748 | rte_prefetch0(&vq->avail->ring[vq->last_avail_idx & (vq->size - 1)]); |
| 3749 | |
| 3750 | async_iter_reset(async); |
| 3751 | |
| 3752 | count = RTE_MIN(count, MAX_PKT_BURST); |
| 3753 | count = RTE_MIN(count, avail_entries); |
| 3754 | VHOST_LOG_DATA(dev->ifname, DEBUG, "about to dequeue %u buffers\n", count); |
| 3755 | |
| 3756 | if (rte_pktmbuf_alloc_bulk(mbuf_pool, pkts_prealloc, count)) |
| 3757 | goto out; |
| 3758 | |
| 3759 | for (pkt_idx = 0; pkt_idx < count; pkt_idx++) { |
| 3760 | uint16_t head_idx = 0; |
| 3761 | uint16_t nr_vec = 0; |
| 3762 | uint16_t to; |
| 3763 | uint32_t buf_len; |
| 3764 | int err; |
| 3765 | struct buf_vector buf_vec[BUF_VECTOR_MAX]; |
| 3766 | struct rte_mbuf *pkt = pkts_prealloc[pkt_idx]; |
| 3767 | |
| 3768 | if (unlikely(fill_vec_buf_split(dev, vq, vq->last_avail_idx, |
| 3769 | &nr_vec, buf_vec, |
| 3770 | &head_idx, &buf_len, |
| 3771 | VHOST_ACCESS_RO) < 0)) { |
| 3772 | dropped = true; |
| 3773 | break; |
| 3774 | } |
| 3775 | |
| 3776 | if (unlikely(buf_len <= dev->vhost_hlen)) { |
| 3777 | dropped = true; |
no test coverage detected