[dpdk-dev] [PATCH v2] virtio: Support mergeable buffer in virtio PMD
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
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
> -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