virtio: retrieve header size from device setting
authorYuanhan Liu <yuanhan.liu@linux.intel.com>
Tue, 2 Feb 2016 13:48:17 +0000 (21:48 +0800)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Wed, 3 Feb 2016 15:07:49 +0000 (16:07 +0100)
The mergeable virtio net hdr format has been the standard and the
only virtio net hdr format since virtio 1.0. Therefore, we can
not hardcode hdr_size to "sizeof(struct virtio_net_hdr)" any more
at virtio_recv_pkts(), otherwise, there would be a mismatch of
hdr size from rte_vhost_enqueue_burst() and virtio_recv_pkts(),
leading a packet corruption.

Instead, we should retrieve it from hw->vtnet_hdr_size; we will
do proper settings at eth_virtio_dev_init() in later patches.

Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Tested-by: Qian Xu <qian.q.xu@intel.com>
Reviewed-by: Tetsuya Mukawa <mukawa@igel.co.jp>
Tested-by: Tetsuya Mukawa <mukawa@igel.co.jp>
Acked-by: Huawei Xie <huawei.xie@intel.com>
drivers/net/virtio/virtio_rxtx.c
drivers/net/virtio/virtio_rxtx_simple.c

index b7267c0..41a1366 100644 (file)
@@ -560,7 +560,7 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
        struct rte_mbuf *rcv_pkts[VIRTIO_MBUF_BURST_SZ];
        int error;
        uint32_t i, nb_enqueued;
-       const uint32_t hdr_size = sizeof(struct virtio_net_hdr);
+       uint32_t hdr_size;
 
        nb_used = VIRTQUEUE_NUSED(rxvq);
 
@@ -580,6 +580,7 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
        hw = rxvq->hw;
        nb_rx = 0;
        nb_enqueued = 0;
+       hdr_size = hw->vtnet_hdr_size;
 
        for (i = 0; i < num ; i++) {
                rxm = rcv_pkts[i];
@@ -664,7 +665,7 @@ virtio_recv_mergeable_pkts(void *rx_queue,
        uint32_t seg_num;
        uint16_t extra_idx;
        uint32_t seg_res;
-       const uint32_t hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);
+       uint32_t hdr_size;
 
        nb_used = VIRTQUEUE_NUSED(rxvq);
 
@@ -682,6 +683,7 @@ virtio_recv_mergeable_pkts(void *rx_queue,
        seg_num = 0;
        extra_idx = 0;
        seg_res = 0;
+       hdr_size = hw->vtnet_hdr_size;
 
        while (i < nb_used) {
                struct virtio_net_hdr_mrg_rxbuf *header;
index ff3c11a..3a1de9d 100644 (file)
@@ -81,9 +81,9 @@ virtqueue_enqueue_recv_refill_simple(struct virtqueue *vq,
 
        start_dp = vq->vq_ring.desc;
        start_dp[desc_idx].addr = (uint64_t)((uintptr_t)cookie->buf_physaddr +
-               RTE_PKTMBUF_HEADROOM - sizeof(struct virtio_net_hdr));
+               RTE_PKTMBUF_HEADROOM - vq->hw->vtnet_hdr_size);
        start_dp[desc_idx].len = cookie->buf_len -
-               RTE_PKTMBUF_HEADROOM + sizeof(struct virtio_net_hdr);
+               RTE_PKTMBUF_HEADROOM + vq->hw->vtnet_hdr_size;
 
        vq->vq_free_cnt--;
        vq->vq_avail_idx++;
@@ -120,9 +120,9 @@ virtio_rxq_rearm_vec(struct virtqueue *rxvq)
 
                start_dp[i].addr =
                        (uint64_t)((uintptr_t)sw_ring[i]->buf_physaddr +
-                       RTE_PKTMBUF_HEADROOM - sizeof(struct virtio_net_hdr));
+                       RTE_PKTMBUF_HEADROOM - rxvq->hw->vtnet_hdr_size);
                start_dp[i].len = sw_ring[i]->buf_len -
-                       RTE_PKTMBUF_HEADROOM + sizeof(struct virtio_net_hdr);
+                       RTE_PKTMBUF_HEADROOM + rxvq->hw->vtnet_hdr_size;
        }
 
        rxvq->vq_avail_idx += RTE_VIRTIO_VPMD_RX_REARM_THRESH;
@@ -175,8 +175,8 @@ virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
        len_adjust = _mm_set_epi16(
                0, 0,
                0,
-               (uint16_t) -sizeof(struct virtio_net_hdr),
-               0, (uint16_t) -sizeof(struct virtio_net_hdr),
+               (uint16_t)-rxvq->hw->vtnet_hdr_size,
+               0, (uint16_t)-rxvq->hw->vtnet_hdr_size,
                0, 0);
 
        if (unlikely(nb_pkts < RTE_VIRTIO_DESC_PER_LOOP))