[dpdk-dev] [PATCH v2] virtio: Support mergeable buffer in virtio PMD

2014-07-30 Thread Fu, JingguoX
Tested-by: Jingguo Fu 

This patch includes 1 file, and has been tested by Intel.
Please see information as the following:

Host:
Fedora 19 x86_64, Linux Kernel 3.9.0, GCC 4.8.2  Intel Xeon CPU E5-2680 v2 @ 
2.80GHz
 NIC: Intel Niantic 82599, Intel i350, Intel 82580 and Intel 82576
Guest:
Fedora 16 x86_64, Linux Kernel 3.4.2, GCC 4.6.3 Qemu emulator 1.4.2 

We verified Linux legacy regression tests for normal frame, Linux Legacy jumbo 
frame / scatter gather tests, vhost regression tests Include zero copy and one 
copy test cases for normal frame.

Total case  Passed Failed
   1010  0


-Original Message-
From: dev [mailto:dev-boun...@dpdk.org] On Behalf Of Ouyang Changchun
Sent: Friday, July 25, 2014 2:03 PM
To: dev at dpdk.org
Subject: [dpdk-dev] [PATCH v2] virtio: Support mergeable buffer in virtio PMD

v2 change: 
- Resolve conflicts wiht the tip code; 
- And resolve 2 issues: 
   -- fix mbuf leak when discard a uncompleted packet.
   -- refine pkt.data to point to actual payload data start point.  

v1 change: 
This patch supports mergeable buffer feature in DPDK based virtio PMD, which can
receive jumbo frame with larger size, like 3K, 4K or even 9K.

Signed-off-by: Changchun Ouyang 
---
 lib/librte_pmd_virtio/virtio_ethdev.c |  20 ++--
 lib/librte_pmd_virtio/virtio_ethdev.h |   3 +
 lib/librte_pmd_virtio/virtio_rxtx.c   | 206 +-
 3 files changed, 194 insertions(+), 35 deletions(-)

diff --git a/lib/librte_pmd_virtio/virtio_ethdev.c 
b/lib/librte_pmd_virtio/virtio_ethdev.c
index b9f5529..535d798 100644
--- a/lib/librte_pmd_virtio/virtio_ethdev.c
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c
@@ -337,7 +337,7 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
snprintf(vq_name, sizeof(vq_name), "port%d_tvq%d_hdrzone",
dev->data->port_id, queue_idx);
vq->virtio_net_hdr_mz = rte_memzone_reserve_aligned(vq_name,
-   vq_size * sizeof(struct virtio_net_hdr),
+   vq_size * hw->vtnet_hdr_size,
socket_id, 0, CACHE_LINE_SIZE);
if (vq->virtio_net_hdr_mz == NULL) {
rte_free(vq);
@@ -346,7 +346,7 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
vq->virtio_net_hdr_mem =
vq->virtio_net_hdr_mz->phys_addr;
memset(vq->virtio_net_hdr_mz->addr, 0,
-   vq_size * sizeof(struct virtio_net_hdr));
+   vq_size * hw->vtnet_hdr_size);
} else if (queue_type == VTNET_CQ) {
/* Allocate a page for control vq command, data and status */
snprintf(vq_name, sizeof(vq_name), "port%d_cvq_hdrzone",
@@ -571,9 +571,6 @@ virtio_negotiate_features(struct virtio_hw *hw)
mask |= VIRTIO_NET_F_GUEST_TSO4 | VIRTIO_NET_F_GUEST_TSO6 | 
VIRTIO_NET_F_GUEST_ECN;
mask |= VTNET_LRO_FEATURES;

-   /* rx_mbuf should not be in multiple merged segments */
-   mask |= VIRTIO_NET_F_MRG_RXBUF;
-
/* not negotiating INDIRECT descriptor table support */
mask |= VIRTIO_RING_F_INDIRECT_DESC;

@@ -746,7 +743,6 @@ eth_virtio_dev_init(__rte_unused struct eth_driver *eth_drv,
}

eth_dev->dev_ops = _eth_dev_ops;
-   eth_dev->rx_pkt_burst = _recv_pkts;
eth_dev->tx_pkt_burst = _xmit_pkts;

if (rte_eal_process_type() == RTE_PROC_SECONDARY)
@@ -801,10 +797,13 @@ eth_virtio_dev_init(__rte_unused struct eth_driver 
*eth_drv,
virtio_negotiate_features(hw);

/* Setting up rx_header size for the device */
-   if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF))
+   if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
+   eth_dev->rx_pkt_burst = _recv_mergeable_pkts;
hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);
-   else
+   } else {
+   eth_dev->rx_pkt_burst = _recv_pkts;
hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr);
+   }

/* Allocate memory for storing MAC addresses */
eth_dev->data->mac_addrs = rte_zmalloc("virtio", ETHER_ADDR_LEN, 0);
@@ -1009,7 +1008,7 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)

while ((buf = (struct rte_mbuf *)virtqueue_detatch_unused(
dev->data->rx_queues[i])) != NULL) {
-   rte_pktmbuf_free_seg(buf);
+   rte_pktmbuf_free(buf);
mbuf_num++;
}

@@ -1028,7 +1027,8 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)
mbuf_num = 0;
while ((buf = (struct rte_mbuf *)virtqueue_detatch_unused(
dev->data->tx_queues[i])) != NULL) {
-   rte_pk

[dpdk-dev] [PATCH v2] virtio: Support mergeable buffer in virtio PMD

2014-07-25 Thread Ouyang Changchun
v2 change: 
- Resolve conflicts wiht the tip code; 
- And resolve 2 issues: 
   -- fix mbuf leak when discard a uncompleted packet.
   -- refine pkt.data to point to actual payload data start point.  

v1 change: 
This patch supports mergeable buffer feature in DPDK based virtio PMD, which can
receive jumbo frame with larger size, like 3K, 4K or even 9K.

Signed-off-by: Changchun Ouyang 
---
 lib/librte_pmd_virtio/virtio_ethdev.c |  20 ++--
 lib/librte_pmd_virtio/virtio_ethdev.h |   3 +
 lib/librte_pmd_virtio/virtio_rxtx.c   | 206 +-
 3 files changed, 194 insertions(+), 35 deletions(-)

diff --git a/lib/librte_pmd_virtio/virtio_ethdev.c 
b/lib/librte_pmd_virtio/virtio_ethdev.c
index b9f5529..535d798 100644
--- a/lib/librte_pmd_virtio/virtio_ethdev.c
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c
@@ -337,7 +337,7 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
snprintf(vq_name, sizeof(vq_name), "port%d_tvq%d_hdrzone",
dev->data->port_id, queue_idx);
vq->virtio_net_hdr_mz = rte_memzone_reserve_aligned(vq_name,
-   vq_size * sizeof(struct virtio_net_hdr),
+   vq_size * hw->vtnet_hdr_size,
socket_id, 0, CACHE_LINE_SIZE);
if (vq->virtio_net_hdr_mz == NULL) {
rte_free(vq);
@@ -346,7 +346,7 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
vq->virtio_net_hdr_mem =
vq->virtio_net_hdr_mz->phys_addr;
memset(vq->virtio_net_hdr_mz->addr, 0,
-   vq_size * sizeof(struct virtio_net_hdr));
+   vq_size * hw->vtnet_hdr_size);
} else if (queue_type == VTNET_CQ) {
/* Allocate a page for control vq command, data and status */
snprintf(vq_name, sizeof(vq_name), "port%d_cvq_hdrzone",
@@ -571,9 +571,6 @@ virtio_negotiate_features(struct virtio_hw *hw)
mask |= VIRTIO_NET_F_GUEST_TSO4 | VIRTIO_NET_F_GUEST_TSO6 | 
VIRTIO_NET_F_GUEST_ECN;
mask |= VTNET_LRO_FEATURES;

-   /* rx_mbuf should not be in multiple merged segments */
-   mask |= VIRTIO_NET_F_MRG_RXBUF;
-
/* not negotiating INDIRECT descriptor table support */
mask |= VIRTIO_RING_F_INDIRECT_DESC;

@@ -746,7 +743,6 @@ eth_virtio_dev_init(__rte_unused struct eth_driver *eth_drv,
}

eth_dev->dev_ops = _eth_dev_ops;
-   eth_dev->rx_pkt_burst = _recv_pkts;
eth_dev->tx_pkt_burst = _xmit_pkts;

if (rte_eal_process_type() == RTE_PROC_SECONDARY)
@@ -801,10 +797,13 @@ eth_virtio_dev_init(__rte_unused struct eth_driver 
*eth_drv,
virtio_negotiate_features(hw);

/* Setting up rx_header size for the device */
-   if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF))
+   if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
+   eth_dev->rx_pkt_burst = _recv_mergeable_pkts;
hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);
-   else
+   } else {
+   eth_dev->rx_pkt_burst = _recv_pkts;
hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr);
+   }

/* Allocate memory for storing MAC addresses */
eth_dev->data->mac_addrs = rte_zmalloc("virtio", ETHER_ADDR_LEN, 0);
@@ -1009,7 +1008,7 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)

while ((buf = (struct rte_mbuf *)virtqueue_detatch_unused(
dev->data->rx_queues[i])) != NULL) {
-   rte_pktmbuf_free_seg(buf);
+   rte_pktmbuf_free(buf);
mbuf_num++;
}

@@ -1028,7 +1027,8 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)
mbuf_num = 0;
while ((buf = (struct rte_mbuf *)virtqueue_detatch_unused(
dev->data->tx_queues[i])) != NULL) {
-   rte_pktmbuf_free_seg(buf);
+   rte_pktmbuf_free(buf);
+
mbuf_num++;
}

diff --git a/lib/librte_pmd_virtio/virtio_ethdev.h 
b/lib/librte_pmd_virtio/virtio_ethdev.h
index 858e644..d2e1eed 100644
--- a/lib/librte_pmd_virtio/virtio_ethdev.h
+++ b/lib/librte_pmd_virtio/virtio_ethdev.h
@@ -104,6 +104,9 @@ int  virtio_dev_tx_queue_setup(struct rte_eth_dev *dev, 
uint16_t tx_queue_id,
 uint16_t virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);

+uint16_t virtio_recv_mergeable_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+   uint16_t nb_pkts);
+
 uint16_t virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);

diff --git a/lib/librte_pmd_virtio/virtio_rxtx.c 
b/lib/librte_pmd_virtio/virtio_rxtx.c
index fcd8bd1..3d81b34 100644
--- a/lib/librte_pmd_virtio/virtio_rxtx.c
+++ b/lib/librte_pmd_virtio/virtio_rxtx.c

[dpdk-dev] [PATCH v2] virtio: Support mergeable buffer in virtio PMD

2014-07-25 Thread Xie, Huawei


> -Original Message-
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Ouyang Changchun
> Sent: Friday, July 25, 2014 2:03 PM
> To: dev at dpdk.org
> Subject: [dpdk-dev] [PATCH v2] virtio: Support mergeable buffer in virtio PMD
> 
> v2 change:
> - Resolve conflicts wiht the tip code;
> - And resolve 2 issues:
>-- fix mbuf leak when discard a uncompleted packet.
>-- refine pkt.data to point to actual payload data start point.
> 
> v1 change:
> This patch supports mergeable buffer feature in DPDK based virtio PMD, which
> can
> receive jumbo frame with larger size, like 3K, 4K or even 9K.
> 
> Signed-off-by: Changchun Ouyang 
> ---
>  lib/librte_pmd_virtio/virtio_ethdev.c |  20 ++--
>  lib/librte_pmd_virtio/virtio_ethdev.h |   3 +
>  lib/librte_pmd_virtio/virtio_rxtx.c   | 206 +---
> --
>  3 files changed, 194 insertions(+), 35 deletions(-)
> 
> diff --git a/lib/librte_pmd_virtio/virtio_ethdev.c
> b/lib/librte_pmd_virtio/virtio_ethdev.c
> index b9f5529..535d798 100644
> --- a/lib/librte_pmd_virtio/virtio_ethdev.c
> +++ b/lib/librte_pmd_virtio/virtio_ethdev.c
> @@ -337,7 +337,7 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
>   snprintf(vq_name, sizeof(vq_name), "port%d_tvq%d_hdrzone",
>   dev->data->port_id, queue_idx);
>   vq->virtio_net_hdr_mz =
> rte_memzone_reserve_aligned(vq_name,
> - vq_size * sizeof(struct virtio_net_hdr),
> + vq_size * hw->vtnet_hdr_size,
>   socket_id, 0, CACHE_LINE_SIZE);
>   if (vq->virtio_net_hdr_mz == NULL) {
>   rte_free(vq);
> @@ -346,7 +346,7 @@ int virtio_dev_queue_setup(struct rte_eth_dev *dev,
>   vq->virtio_net_hdr_mem =
>   vq->virtio_net_hdr_mz->phys_addr;
>   memset(vq->virtio_net_hdr_mz->addr, 0,
> - vq_size * sizeof(struct virtio_net_hdr));
> + vq_size * hw->vtnet_hdr_size);
>   } else if (queue_type == VTNET_CQ) {
>   /* Allocate a page for control vq command, data and status */
>   snprintf(vq_name, sizeof(vq_name), "port%d_cvq_hdrzone",
> @@ -571,9 +571,6 @@ virtio_negotiate_features(struct virtio_hw *hw)
>   mask |= VIRTIO_NET_F_GUEST_TSO4 | VIRTIO_NET_F_GUEST_TSO6 |
> VIRTIO_NET_F_GUEST_ECN;
>   mask |= VTNET_LRO_FEATURES;
> 
> - /* rx_mbuf should not be in multiple merged segments */
> - mask |= VIRTIO_NET_F_MRG_RXBUF;
> -
>   /* not negotiating INDIRECT descriptor table support */
>   mask |= VIRTIO_RING_F_INDIRECT_DESC;
> 
> @@ -746,7 +743,6 @@ eth_virtio_dev_init(__rte_unused struct eth_driver
> *eth_drv,
>   }
> 
>   eth_dev->dev_ops = _eth_dev_ops;
> - eth_dev->rx_pkt_burst = _recv_pkts;
>   eth_dev->tx_pkt_burst = _xmit_pkts;
> 
>   if (rte_eal_process_type() == RTE_PROC_SECONDARY)
> @@ -801,10 +797,13 @@ eth_virtio_dev_init(__rte_unused struct eth_driver
> *eth_drv,
>   virtio_negotiate_features(hw);
> 
>   /* Setting up rx_header size for the device */
> - if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF))
> + if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
> + eth_dev->rx_pkt_burst = _recv_mergeable_pkts;
>   hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);
> - else
> + } else {
> + eth_dev->rx_pkt_burst = _recv_pkts;
>   hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr);
> + }
> 
>   /* Allocate memory for storing MAC addresses */
>   eth_dev->data->mac_addrs = rte_zmalloc("virtio", ETHER_ADDR_LEN,
> 0);
> @@ -1009,7 +1008,7 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev
> *dev)
> 
>   while ((buf = (struct rte_mbuf *)virtqueue_detatch_unused(
>   dev->data->rx_queues[i])) != NULL) {
> - rte_pktmbuf_free_seg(buf);
> + rte_pktmbuf_free(buf);
>   mbuf_num++;
>   }
> 
> @@ -1028,7 +1027,8 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev
> *dev)
>   mbuf_num = 0;
>   while ((buf = (struct rte_mbuf *)virtqueue_detatch_unused(
>   dev->data->tx_queues[i])) != NULL) {
> - rte_pktmbuf_free_seg(buf);
> + rte_pktmbuf_free(buf);
> +
>   mbuf_num++;
>   }
> 
> diff --git a/lib/librte_pmd_virtio/virtio_ethdev.h
> b/lib