struct virtqueue *vq = txvq->vq;
struct virtio_hw *hw = vq->hw;
uint16_t hdr_size = hw->vtnet_hdr_size;
- uint16_t slots, can_push;
+ uint16_t slots, can_push = 0, use_indirect = 0;
int16_t need;
+ /* optimize ring usage */
+ if ((vtpci_with_feature(hw, VIRTIO_F_ANY_LAYOUT) ||
+ vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) &&
+ rte_mbuf_refcnt_read(txm) == 1 &&
+ RTE_MBUF_DIRECT(txm) &&
+ txm->nb_segs == 1 &&
+ rte_pktmbuf_headroom(txm) >= hdr_size)
+ can_push = 1;
+ else if (vtpci_with_feature(hw, VIRTIO_RING_F_INDIRECT_DESC) &&
+ txm->nb_segs < VIRTIO_MAX_TX_INDIRECT)
+ use_indirect = 1;
/* How many main ring entries are needed to this Tx?
+ * indirect => 1
* any_layout => number of segments
* default => number of segments + 1
*/
- can_push = rte_mbuf_refcnt_read(txm) == 1 &&
- RTE_MBUF_DIRECT(txm) &&
- txm->nb_segs == 1 &&
- rte_pktmbuf_headroom(txm) >= hdr_size;
-
- slots = txm->nb_segs + !can_push;
+ slots = use_indirect ? 1 : (txm->nb_segs + !can_push);
need = slots - vq->vq_free_cnt;
/* Positive value indicates it need free vring descriptors */
}
/* Enqueue Packet buffers */
- virtqueue_enqueue_xmit_packed(txvq, txm, slots, can_push, 1);
+ virtqueue_enqueue_xmit_packed(txvq, txm, slots, use_indirect,
+ can_push, 1);
txvq->stats.bytes += txm->pkt_len;
return 0;
*/
uint16_t csum = 0, off;
- rte_raw_cksum_mbuf(m, hdr->csum_start,
+ if (rte_raw_cksum_mbuf(m, hdr->csum_start,
rte_pktmbuf_pkt_len(m) - hdr->csum_start,
- &csum);
+ &csum) < 0)
+ return -1;
if (likely(csum != 0xffff))
csum = ~csum;
off = hdr->csum_offset + hdr->csum_start;
return -1;
/* only care avail/used bits */
+#if defined(RTE_ARCH_I686)
+ __m512i v_mask = _mm512_set4_epi64(PACKED_FLAGS_MASK, 0x0,
+ PACKED_FLAGS_MASK, 0x0);
+#else
__m512i v_mask = _mm512_maskz_set1_epi64(0xaa, PACKED_FLAGS_MASK);
+#endif
desc_addr = &vq->vq_packed.ring.desc[id];
__m512i v_desc = _mm512_loadu_si512(desc_addr);
__m512i v_used_flag = _mm512_setzero_si512();
if (vq->vq_packed.used_wrap_counter)
+#if defined(RTE_ARCH_I686)
+ v_used_flag = _mm512_set4_epi64(PACKED_FLAGS_MASK, 0x0,
+ PACKED_FLAGS_MASK, 0x0);
+#else
v_used_flag = _mm512_maskz_set1_epi64(0xaa, PACKED_FLAGS_MASK);
+#endif
/* Check all descs are used */
desc_stats = _mm512_cmpneq_epu64_mask(v_flag, v_used_flag);