* [dpdk-dev] [RFC 01/29] net/virtio: vring init for 1.1
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 02/29] net/virtio: implement 1.1 guest Tx Tiwei Bie
` (27 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu, Jens Freimann
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Add and initialize descriptor data structures.
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
[rename desc_1_1 to vring_desc_1_1, refactor desc init code]
Signed-off-by: Jens Freimann <jfreiman@redhat.com>
---
drivers/net/virtio/virtio-1.1.h | 19 +++++++++++++++++++
drivers/net/virtio/virtio_ethdev.c | 22 ++++++++++++----------
drivers/net/virtio/virtio_pci.h | 7 +++++++
drivers/net/virtio/virtio_ring.h | 15 +++++++++++++--
drivers/net/virtio/virtqueue.h | 10 ++++++++++
5 files changed, 61 insertions(+), 12 deletions(-)
create mode 100644 drivers/net/virtio/virtio-1.1.h
diff --git a/drivers/net/virtio/virtio-1.1.h b/drivers/net/virtio/virtio-1.1.h
new file mode 100644
index 0000000..48cbb18
--- /dev/null
+++ b/drivers/net/virtio/virtio-1.1.h
@@ -0,0 +1,19 @@
+#ifndef __VIRTIO_1_1_H
+#define __VIRTIO_1_1_H
+
+#define VRING_DESC_F_NEXT 1
+#define VRING_DESC_F_WRITE 2
+#define VRING_DESC_F_INDIRECT 4
+
+#define BATCH_NOT_FIRST 0x0010
+#define BATCH_NOT_LAST 0x0020
+#define DESC_HW 0x0080
+
+struct vring_desc_1_1 {
+ uint64_t addr;
+ uint32_t len;
+ uint16_t index;
+ uint16_t flags;
+};
+
+#endif /* __VIRTIO_1_1_H */
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 66c28ac..7c4799a 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -320,19 +320,21 @@ virtio_init_vring(struct virtqueue *vq)
PMD_INIT_FUNC_TRACE();
- /*
- * Reinitialise since virtio port might have been stopped and restarted
- */
memset(ring_mem, 0, vq->vq_ring_size);
- vring_init(vr, size, ring_mem, VIRTIO_PCI_VRING_ALIGN);
- vq->vq_used_cons_idx = 0;
- vq->vq_desc_head_idx = 0;
- vq->vq_avail_idx = 0;
- vq->vq_desc_tail_idx = (uint16_t)(vq->vq_nentries - 1);
+ vring_init(vq->hw, vr, size, ring_mem, VIRTIO_PCI_VRING_ALIGN);
+
vq->vq_free_cnt = vq->vq_nentries;
memset(vq->vq_descx, 0, sizeof(struct vq_desc_extra) * vq->vq_nentries);
+ vq->vq_used_cons_idx = 0;
+ vq->vq_avail_idx = 0;
+ if (vtpci_version_1_1(vq->hw)) {
+ vring_desc_init_1_1(vr, size);
+ } else {
+ vq->vq_desc_head_idx = 0;
+ vq->vq_desc_tail_idx = (uint16_t)(vq->vq_nentries - 1);
- vring_desc_init(vr->desc, size);
+ vring_desc_init(vr->desc, size);
+ }
/*
* Disable device(host) interrupting guest
@@ -407,7 +409,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
/*
* Reserve a memzone for vring elements
*/
- size = vring_size(vq_size, VIRTIO_PCI_VRING_ALIGN);
+ size = vring_size(hw, vq_size, VIRTIO_PCI_VRING_ALIGN);
vq->vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_PCI_VRING_ALIGN);
PMD_INIT_LOG(DEBUG, "vring_size: %d, rounded_vring_size: %d",
size, vq->vq_ring_size);
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 18caebd..ec74009 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -140,6 +140,7 @@ struct virtnet_ctl;
#define VIRTIO_F_VERSION_1 32
#define VIRTIO_F_IOMMU_PLATFORM 33
+#define VIRTIO_F_VERSION_1_1 34
/*
* Some VirtIO feature bits (currently bits 28 through 31) are
@@ -318,6 +319,12 @@ vtpci_with_feature(struct virtio_hw *hw, uint64_t bit)
return (hw->guest_features & (1ULL << bit)) != 0;
}
+static inline int
+vtpci_version_1_1(struct virtio_hw *hw)
+{
+ return vtpci_with_feature(hw, VIRTIO_F_VERSION_1_1);
+}
+
/*
* Function declaration from virtio_pci.c
*/
diff --git a/drivers/net/virtio/virtio_ring.h b/drivers/net/virtio/virtio_ring.h
index fcecc16..a991092 100644
--- a/drivers/net/virtio/virtio_ring.h
+++ b/drivers/net/virtio/virtio_ring.h
@@ -38,6 +38,8 @@
#include <rte_common.h>
+#include "virtio-1.1.h"
+
/* This marks a buffer as continuing via the next field. */
#define VRING_DESC_F_NEXT 1
/* This marks a buffer as write-only (otherwise read-only). */
@@ -88,6 +90,7 @@ struct vring {
struct vring_desc *desc;
struct vring_avail *avail;
struct vring_used *used;
+ struct vring_desc_1_1 *desc_1_1;
};
/* The standard layout for the ring is a continuous chunk of memory which
@@ -124,10 +127,13 @@ struct vring {
#define vring_avail_event(vr) (*(uint16_t *)&(vr)->used->ring[(vr)->num])
static inline size_t
-vring_size(unsigned int num, unsigned long align)
+vring_size(struct virtio_hw *hw, unsigned int num, unsigned long align)
{
size_t size;
+ if (vtpci_version_1_1(hw))
+ return num * sizeof(struct vring_desc_1_1);
+
size = num * sizeof(struct vring_desc);
size += sizeof(struct vring_avail) + (num * sizeof(uint16_t));
size = RTE_ALIGN_CEIL(size, align);
@@ -137,10 +143,15 @@ vring_size(unsigned int num, unsigned long align)
}
static inline void
-vring_init(struct vring *vr, unsigned int num, uint8_t *p,
+vring_init(struct virtio_hw *hw, struct vring *vr, unsigned int num, uint8_t *p,
unsigned long align)
{
vr->num = num;
+ if (vtpci_version_1_1(hw)) {
+ vr->desc_1_1 = (struct vring_desc_1_1 *)p;
+ return;
+ }
+
vr->desc = (struct vring_desc *) p;
vr->avail = (struct vring_avail *) (p +
num * sizeof(struct vring_desc));
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 2e12086..91d2db7 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -266,6 +266,16 @@ struct virtio_tx_region {
__attribute__((__aligned__(16)));
};
+static inline void
+vring_desc_init_1_1(struct vring *vr, int n)
+{
+ int i;
+ for (i = 0; i < n; i++) {
+ struct vring_desc_1_1 *desc = &vr->desc_1_1[i];
+ desc->index = i;
+ }
+}
+
/* Chain all the descriptors in the ring with an END */
static inline void
vring_desc_init(struct vring_desc *dp, uint16_t n)
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 02/29] net/virtio: implement 1.1 guest Tx
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 01/29] net/virtio: vring init for 1.1 Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 03/29] net/virtio-user: add option to enable 1.1 Tiwei Bie
` (26 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
build only so far
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
drivers/net/virtio/Makefile | 1 +
drivers/net/virtio/virtio_ethdev.c | 24 ++++--
drivers/net/virtio/virtio_ethdev.h | 3 +
drivers/net/virtio/virtio_rxtx.c | 3 +
drivers/net/virtio/virtio_rxtx_1.1.c | 159 +++++++++++++++++++++++++++++++++++
5 files changed, 183 insertions(+), 7 deletions(-)
create mode 100644 drivers/net/virtio/virtio_rxtx_1.1.c
diff --git a/drivers/net/virtio/Makefile b/drivers/net/virtio/Makefile
index b21b878..4c4ff42 100644
--- a/drivers/net/virtio/Makefile
+++ b/drivers/net/virtio/Makefile
@@ -49,6 +49,7 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtqueue.c
SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_pci.c
SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_rxtx.c
+SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_rxtx_1.1.c
SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_ethdev.c
SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_rxtx_simple.c
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 7c4799a..35ce07d 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -334,12 +334,12 @@ virtio_init_vring(struct virtqueue *vq)
vq->vq_desc_tail_idx = (uint16_t)(vq->vq_nentries - 1);
vring_desc_init(vr->desc, size);
- }
- /*
- * Disable device(host) interrupting guest
- */
- virtqueue_disable_intr(vq);
+ /*
+ * Disable device(host) interrupting guest
+ */
+ virtqueue_disable_intr(vq);
+ }
}
static int
@@ -625,7 +625,8 @@ virtio_dev_close(struct rte_eth_dev *dev)
}
vtpci_reset(hw);
- virtio_dev_free_mbufs(dev);
+ if (!vtpci_version_1_1(hw))
+ virtio_dev_free_mbufs(dev);
virtio_free_queues(hw);
}
@@ -1535,7 +1536,6 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
RTE_BUILD_BUG_ON(RTE_PKTMBUF_HEADROOM < sizeof(struct virtio_net_hdr_mrg_rxbuf));
eth_dev->dev_ops = &virtio_eth_dev_ops;
- eth_dev->tx_pkt_burst = &virtio_xmit_pkts;
if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
if (!hw->virtio_user_dev) {
@@ -1579,6 +1579,12 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
if (ret < 0)
return ret;
+ /* FIXME: as second process? */
+ if (vtpci_version_1_1(hw))
+ eth_dev->tx_pkt_burst = &virtio_xmit_pkts_1_1;
+ else
+ eth_dev->tx_pkt_burst = &virtio_xmit_pkts;
+
/* Setup interrupt callback */
if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
rte_intr_callback_register(eth_dev->intr_handle,
@@ -1750,6 +1756,10 @@ virtio_dev_start(struct rte_eth_dev *dev)
}
}
+ /*no rx support for virtio 1.1 yet*/
+ if (vtpci_version_1_1(hw))
+ return 0;
+
/*Notify the backend
*Otherwise the tap backend might already stop its queue due to fullness.
*vhost backend will have no chance to be waked up
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index c3413c6..deed34e 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -69,6 +69,7 @@
1u << VIRTIO_NET_F_MTU | \
1u << VIRTIO_RING_F_INDIRECT_DESC | \
1ULL << VIRTIO_F_VERSION_1 | \
+ 1ULL << VIRTIO_F_VERSION_1_1 | \
1ULL << VIRTIO_F_IOMMU_PLATFORM)
#define VIRTIO_PMD_SUPPORTED_GUEST_FEATURES \
@@ -104,6 +105,8 @@ uint16_t virtio_recv_mergeable_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
+uint16_t virtio_xmit_pkts_1_1(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts);
uint16_t virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index fbc96df..e697192 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -427,6 +427,9 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
PMD_INIT_FUNC_TRACE();
+ if (vtpci_version_1_1(hw))
+ return 0;
+
if (nb_desc == 0 || nb_desc > vq->vq_nentries)
nb_desc = vq->vq_nentries;
vq->vq_free_cnt = RTE_MIN(vq->vq_free_cnt, nb_desc);
diff --git a/drivers/net/virtio/virtio_rxtx_1.1.c b/drivers/net/virtio/virtio_rxtx_1.1.c
new file mode 100644
index 0000000..e47a346
--- /dev/null
+++ b/drivers/net/virtio/virtio_rxtx_1.1.c
@@ -0,0 +1,159 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_branch_prediction.h>
+#include <rte_mempool.h>
+#include <rte_malloc.h>
+#include <rte_mbuf.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_prefetch.h>
+#include <rte_string_fns.h>
+#include <rte_errno.h>
+#include <rte_byteorder.h>
+#include <rte_cpuflags.h>
+#include <rte_net.h>
+#include <rte_ip.h>
+#include <rte_udp.h>
+#include <rte_tcp.h>
+
+#include "virtio_logs.h"
+#include "virtio_ethdev.h"
+#include "virtio_pci.h"
+#include "virtqueue.h"
+#include "virtio_rxtx.h"
+
+/* Cleanup from completed transmits. */
+static void
+virtio_xmit_cleanup(struct virtqueue *vq)
+{
+ uint16_t idx;
+ uint16_t size = vq->vq_nentries;
+ struct vring_desc_1_1 *desc = vq->vq_ring.desc_1_1;
+
+ idx = vq->vq_used_cons_idx & (size - 1);
+ while ((desc[idx].flags & DESC_HW) == 0) {
+ struct vq_desc_extra *dxp;
+
+ dxp = &vq->vq_descx[idx];
+ if (dxp->cookie != NULL) {
+ rte_pktmbuf_free(dxp->cookie);
+ dxp->cookie = NULL;
+ }
+
+ idx = (++vq->vq_used_cons_idx) & (size - 1);
+ vq->vq_free_cnt++;
+
+ if (vq->vq_free_cnt >= size)
+ break;
+ }
+}
+
+static inline void
+virtio_xmit(struct virtnet_tx *txvq, struct rte_mbuf *mbuf)
+{
+ struct virtio_tx_region *txr = txvq->virtio_net_hdr_mz->addr;
+ struct virtqueue *vq = txvq->vq;
+ struct vring_desc_1_1 *desc = vq->vq_ring.desc_1_1;
+ uint16_t idx;
+ uint16_t head_idx = (vq->vq_avail_idx++) & (vq->vq_nentries - 1);
+
+ idx = head_idx;
+ vq->vq_free_cnt -= mbuf->nb_segs + 1;
+ vq->vq_descx[idx].cookie = mbuf;
+
+ desc[idx].addr = txvq->virtio_net_hdr_mem +
+ RTE_PTR_DIFF(&txr[idx].tx_hdr, txr);
+ desc[idx].len = vq->hw->vtnet_hdr_size;
+ desc[idx].flags = VRING_DESC_F_NEXT;
+
+ do {
+ idx = (vq->vq_avail_idx++) & (vq->vq_nentries - 1);
+ desc[idx].addr = VIRTIO_MBUF_DATA_DMA_ADDR(mbuf, vq);
+ desc[idx].len = mbuf->data_len;
+ desc[idx].flags = DESC_HW | VRING_DESC_F_NEXT;
+ } while ((mbuf = mbuf->next) != NULL);
+
+ desc[idx].flags &= ~VRING_DESC_F_NEXT;
+
+ /*
+ * update the head last, so that when the host saw such flag
+ * is set, it means all others in the same chain is also set
+ */
+ rte_smp_wmb();
+ desc[head_idx].flags |= DESC_HW;
+}
+
+uint16_t
+virtio_xmit_pkts_1_1(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+{
+ struct virtnet_tx *txvq = tx_queue;
+ struct virtqueue *vq = txvq->vq;
+ uint16_t i;
+
+ if (unlikely(nb_pkts < 1))
+ return nb_pkts;
+
+ PMD_TX_LOG(DEBUG, "%d packets to xmit", nb_pkts);
+
+ for (i = 0; i < nb_pkts; i++) {
+ struct rte_mbuf *txm = tx_pkts[i];
+
+ if (unlikely(txm->nb_segs + 1 > vq->vq_free_cnt)) {
+ virtio_xmit_cleanup(vq);
+
+ if (unlikely(txm->nb_segs + 1 > vq->vq_free_cnt)) {
+ PMD_TX_LOG(ERR,
+ "No free tx descriptors to transmit");
+ break;
+ }
+ }
+
+ virtio_xmit(txvq, txm);
+ txvq->stats.bytes += txm->pkt_len;
+ }
+
+ txvq->stats.packets += i;
+ txvq->stats.errors += nb_pkts - i;
+
+ return i;
+}
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 03/29] net/virtio-user: add option to enable 1.1
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 01/29] net/virtio: vring init for 1.1 Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 02/29] net/virtio: implement 1.1 guest Tx Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 04/29] vhost: enable 1.1 for testing Tiwei Bie
` (25 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
drivers/net/virtio/virtio_user/virtio_user_dev.c | 9 ++++++++-
drivers/net/virtio/virtio_user/virtio_user_dev.h | 3 ++-
drivers/net/virtio/virtio_user_ethdev.c | 14 +++++++++++++-
3 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 450404b..3ff6a05 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -337,7 +337,8 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
int
virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
- int cq, int queue_size, const char *mac, char **ifname)
+ int cq, int queue_size, const char *mac, char **ifname,
+ int version_1_1)
{
snprintf(dev->path, PATH_MAX, "%s", path);
dev->max_queue_pairs = queues;
@@ -365,6 +366,12 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
PMD_INIT_LOG(ERR, "get_features failed: %s", strerror(errno));
return -1;
}
+
+ if (version_1_1)
+ dev->features |= (1ull << VIRTIO_F_VERSION_1_1);
+ else
+ dev->features &= ~(1ull << VIRTIO_F_VERSION_1_1);
+
if (dev->mac_specified)
dev->device_features |= (1ull << VIRTIO_NET_F_MAC);
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h
index 8361b6b..76fa17f 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
@@ -71,7 +71,8 @@ int is_vhost_user_by_type(const char *path);
int virtio_user_start_device(struct virtio_user_dev *dev);
int virtio_user_stop_device(struct virtio_user_dev *dev);
int virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
- int cq, int queue_size, const char *mac, char **ifname);
+ int cq, int queue_size, const char *mac, char **ifname,
+ int version_1_1);
void virtio_user_dev_uninit(struct virtio_user_dev *dev);
void virtio_user_handle_cq(struct virtio_user_dev *dev, uint16_t queue_idx);
#endif
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 280406c..74c7c60 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -300,6 +300,8 @@ static const char *valid_args[] = {
VIRTIO_USER_ARG_QUEUE_SIZE,
#define VIRTIO_USER_ARG_INTERFACE_NAME "iface"
VIRTIO_USER_ARG_INTERFACE_NAME,
+#define VIRTIO_USER_ARG_VERSION_1_1 "version_1_1"
+ VIRTIO_USER_ARG_VERSION_1_1,
NULL
};
@@ -404,6 +406,7 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev)
char *ifname = NULL;
char *mac_addr = NULL;
int ret = -1;
+ uint64_t version_1_1 = 0;
kvlist = rte_kvargs_parse(rte_vdev_device_args(dev), valid_args);
if (!kvlist) {
@@ -478,6 +481,15 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev)
cq = 1;
}
+ if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_VERSION_1_1) == 1) {
+ if (rte_kvargs_process(kvlist, VIRTIO_USER_ARG_VERSION_1_1,
+ &get_integer_arg, &version_1_1) < 0) {
+ PMD_INIT_LOG(ERR, "error to parse %s",
+ VIRTIO_USER_ARG_VERSION_1_1);
+ goto end;
+ }
+ }
+
if (queues > 1 && cq == 0) {
PMD_INIT_LOG(ERR, "multi-q requires ctrl-q");
goto end;
@@ -499,7 +511,7 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev)
hw = eth_dev->data->dev_private;
if (virtio_user_dev_init(hw->virtio_user_dev, path, queues, cq,
- queue_size, mac_addr, &ifname) < 0) {
+ queue_size, mac_addr, &ifname, version_1_1) < 0) {
PMD_INIT_LOG(ERR, "virtio_user_dev_init fails");
virtio_user_eth_dev_free(eth_dev);
goto end;
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 04/29] vhost: enable 1.1 for testing
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (2 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 03/29] net/virtio-user: add option to enable 1.1 Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 05/29] vhost: set desc addr for 1.1 Tiwei Bie
` (24 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Just set the features on, no actual work has been done. Just
make sure the virtio PMD could have this feature been enabled,
for testing only.
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
lib/librte_vhost/vhost.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index ddd8a9c..208b2eb 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -138,6 +138,9 @@ struct vhost_virtqueue {
#ifndef VIRTIO_F_VERSION_1
#define VIRTIO_F_VERSION_1 32
#endif
+#ifndef VIRTIO_F_VERSION_1_1
+ #define VIRTIO_F_VERSION_1_1 34
+#endif
#define VHOST_USER_F_PROTOCOL_FEATURES 30
@@ -148,6 +151,7 @@ struct vhost_virtqueue {
(1ULL << VIRTIO_NET_F_GUEST_ANNOUNCE) | \
(1ULL << VIRTIO_NET_F_MQ) | \
(1ULL << VIRTIO_F_VERSION_1) | \
+ (1ULL << VIRTIO_F_VERSION_1_1) | \
(1ULL << VHOST_F_LOG_ALL) | \
(1ULL << VHOST_USER_F_PROTOCOL_FEATURES) | \
(1ULL << VIRTIO_NET_F_HOST_TSO4) | \
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 05/29] vhost: set desc addr for 1.1
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (3 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 04/29] vhost: enable 1.1 for testing Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 06/29] vhost: implement virtio 1.1 dequeue path Tiwei Bie
` (23 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
lib/librte_vhost/vhost.h | 1 +
lib/librte_vhost/vhost_user.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 208b2eb..f3b7ad5 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -86,6 +86,7 @@ TAILQ_HEAD(zcopy_mbuf_list, zcopy_mbuf);
*/
struct vhost_virtqueue {
struct vring_desc *desc;
+ struct vring_desc_1_1 *desc_1_1;
struct vring_avail *avail;
struct vring_used *used;
uint32_t size;
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index e90b44c..3a2de79 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -351,6 +351,7 @@ vhost_user_set_vring_addr(struct virtio_net *dev, VhostUserMsg *msg)
dev->vid);
return -1;
}
+ vq->desc_1_1 = (struct vring_desc_1_1 *)vq->desc;
dev = numa_realloc(dev, msg->payload.addr.index);
vq = dev->virtqueue[msg->payload.addr.index];
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 06/29] vhost: implement virtio 1.1 dequeue path
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (4 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 05/29] vhost: set desc addr for 1.1 Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 07/29] vhost: mark desc being used Tiwei Bie
` (22 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu, Jens Freimann
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Build test only; haven't tested it yet
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Signed-off-by: Jens Freimann <jfreiman@redhat.com>
---
lib/librte_vhost/virtio-1.1.h | 23 ++++++
lib/librte_vhost/virtio_net.c | 181 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 204 insertions(+)
create mode 100644 lib/librte_vhost/virtio-1.1.h
diff --git a/lib/librte_vhost/virtio-1.1.h b/lib/librte_vhost/virtio-1.1.h
new file mode 100644
index 0000000..4241d0a
--- /dev/null
+++ b/lib/librte_vhost/virtio-1.1.h
@@ -0,0 +1,23 @@
+#ifndef __VIRTIO_1_1_H
+#define __VIRTIO_1_1_H
+
+#define __le64 uint64_t
+#define __le32 uint32_t
+#define __le16 uint16_t
+
+#define VRING_DESC_F_NEXT 1
+#define VRING_DESC_F_WRITE 2
+#define VRING_DESC_F_INDIRECT 4
+
+#define BATCH_NOT_FIRST 0x0010
+#define BATCH_NOT_LAST 0x0020
+#define DESC_HW 0x0080
+
+struct vring_desc_1_1 {
+ __le64 addr;
+ __le32 len;
+ __le16 index;
+ __le16 flags;
+};
+
+#endif /* __VIRTIO_1_1_H */
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index 48219e0..fd6f200 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -46,6 +46,7 @@
#include <rte_arp.h>
#include "vhost.h"
+#include "virtio-1.1.h"
#define MAX_PKT_BURST 32
@@ -973,6 +974,183 @@ mbuf_is_consumed(struct rte_mbuf *m)
return true;
}
+static inline uint16_t
+dequeue_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
+ struct rte_mempool *mbuf_pool, struct rte_mbuf *m,
+ struct vring_desc_1_1 *descs)
+{
+ struct vring_desc_1_1 *desc;
+ uint64_t desc_addr;
+ uint32_t desc_avail, desc_offset;
+ uint32_t mbuf_avail, mbuf_offset;
+ uint32_t cpy_len;
+ struct rte_mbuf *cur = m, *prev = m;
+ struct virtio_net_hdr *hdr = NULL;
+ uint16_t head_idx = vq->last_used_idx;
+
+ desc = &descs[(head_idx++) & (vq->size - 1)];
+ if (unlikely((desc->len < dev->vhost_hlen)) ||
+ (desc->flags & VRING_DESC_F_INDIRECT))
+ return -1;
+
+ desc_addr = rte_vhost_gpa_to_vva(dev->mem, desc->addr);
+ if (unlikely(!desc_addr))
+ return -1;
+
+ if (virtio_net_with_host_offload(dev)) {
+ hdr = (struct virtio_net_hdr *)((uintptr_t)desc_addr);
+ rte_prefetch0(hdr);
+ }
+
+ /*
+ * A virtio driver normally uses at least 2 desc buffers
+ * for Tx: the first for storing the header, and others
+ * for storing the data.
+ */
+ if (likely((desc->len == dev->vhost_hlen) &&
+ (desc->flags & VRING_DESC_F_NEXT) != 0)) {
+ desc->flags = 0;
+
+ desc = &descs[(head_idx++) & (vq->size - 1)];
+ if (unlikely(desc->flags & VRING_DESC_F_INDIRECT))
+ return -1;
+
+ desc_addr = rte_vhost_gpa_to_vva(dev->mem, desc->addr);
+ if (unlikely(!desc_addr))
+ return -1;
+
+ desc_offset = 0;
+ desc_avail = desc->len;
+ } else {
+ desc_avail = desc->len - dev->vhost_hlen;
+ desc_offset = dev->vhost_hlen;
+ }
+
+ rte_prefetch0((void *)(uintptr_t)(desc_addr + desc_offset));
+
+ PRINT_PACKET(dev, (uintptr_t)(desc_addr + desc_offset), desc_avail, 0);
+
+ mbuf_offset = 0;
+ mbuf_avail = m->buf_len - RTE_PKTMBUF_HEADROOM;
+ while (1) {
+ uint64_t hpa;
+
+ cpy_len = RTE_MIN(desc_avail, mbuf_avail);
+
+ /*
+ * A desc buf might across two host physical pages that are
+ * not continuous. In such case (gpa_to_hpa returns 0), data
+ * will be copied even though zero copy is enabled.
+ */
+ if (unlikely(dev->dequeue_zero_copy && (hpa = gpa_to_hpa(dev,
+ desc->addr + desc_offset, cpy_len)))) {
+ cur->data_len = cpy_len;
+ cur->data_off = 0;
+ cur->buf_addr = (void *)(uintptr_t)desc_addr;
+ cur->buf_physaddr = hpa;
+
+ /*
+ * In zero copy mode, one mbuf can only reference data
+ * for one or partial of one desc buff.
+ */
+ mbuf_avail = cpy_len;
+ } else {
+ rte_memcpy(rte_pktmbuf_mtod_offset(cur, void *,
+ mbuf_offset),
+ (void *)((uintptr_t)(desc_addr + desc_offset)),
+ cpy_len);
+ }
+
+ mbuf_avail -= cpy_len;
+ mbuf_offset += cpy_len;
+ desc_avail -= cpy_len;
+ desc_offset += cpy_len;
+
+ /* This desc reaches to its end, get the next one */
+ if (desc_avail == 0) {
+ desc->flags = 0;
+
+ if ((desc->flags & VRING_DESC_F_NEXT) == 0)
+ break;
+
+ desc = &descs[(head_idx++) & (vq->size - 1)];
+ if (unlikely(desc->flags & VRING_DESC_F_INDIRECT))
+ return -1;
+
+ desc_addr = rte_vhost_gpa_to_vva(dev->mem, desc->addr);
+ if (unlikely(!desc_addr))
+ return -1;
+
+ rte_prefetch0((void *)(uintptr_t)desc_addr);
+
+ desc_offset = 0;
+ desc_avail = desc->len;
+
+ PRINT_PACKET(dev, (uintptr_t)desc_addr, desc->len, 0);
+ }
+
+ /*
+ * This mbuf reaches to its end, get a new one
+ * to hold more data.
+ */
+ if (mbuf_avail == 0) {
+ cur = rte_pktmbuf_alloc(mbuf_pool);
+ if (unlikely(cur == NULL)) {
+ RTE_LOG(ERR, VHOST_DATA, "Failed to "
+ "allocate memory for mbuf.\n");
+ return -1;
+ }
+
+ prev->next = cur;
+ prev->data_len = mbuf_offset;
+ m->nb_segs += 1;
+ m->pkt_len += mbuf_offset;
+ prev = cur;
+
+ mbuf_offset = 0;
+ mbuf_avail = cur->buf_len - RTE_PKTMBUF_HEADROOM;
+ }
+ }
+ desc->flags = 0;
+
+ prev->data_len = mbuf_offset;
+ m->pkt_len += mbuf_offset;
+
+ if (hdr)
+ vhost_dequeue_offload(hdr, m);
+
+ vq->last_used_idx = head_idx;
+
+ return 0;
+}
+
+static inline uint16_t
+vhost_dequeue_burst_1_1(struct virtio_net *dev, struct vhost_virtqueue *vq,
+ struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts,
+ uint16_t count)
+{
+ uint16_t i;
+ uint16_t idx;
+ struct vring_desc_1_1 *desc = vq->desc_1_1;
+
+ for (i = 0; i < count; i++) {
+ idx = vq->last_used_idx & (vq->size - 1);
+ if (!(desc[idx].flags & DESC_HW))
+ break;
+
+ pkts[i] = rte_pktmbuf_alloc(mbuf_pool);
+ if (unlikely(pkts[i] == NULL)) {
+ RTE_LOG(ERR, VHOST_DATA,
+ "Failed to allocate memory for mbuf.\n");
+ break;
+ }
+
+ dequeue_desc(dev, vq, mbuf_pool, pkts[i], desc);
+ }
+
+ return i;
+}
+
uint16_t
rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
@@ -1000,6 +1178,9 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
if (unlikely(vq->enabled == 0))
return 0;
+ if (dev->features & (1ULL << VIRTIO_F_VERSION_1_1))
+ return vhost_dequeue_burst_1_1(dev, vq, mbuf_pool, pkts, count);
+
if (unlikely(dev->dequeue_zero_copy)) {
struct zcopy_mbuf *zmbuf, *next;
int nr_updated = 0;
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 07/29] vhost: mark desc being used
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (5 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 06/29] vhost: implement virtio 1.1 dequeue path Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 08/29] xxx: batch the desc_hw update? Tiwei Bie
` (21 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
lib/librte_vhost/virtio_net.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index fd6f200..df88e31 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -1009,6 +1009,7 @@ dequeue_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
*/
if (likely((desc->len == dev->vhost_hlen) &&
(desc->flags & VRING_DESC_F_NEXT) != 0)) {
+ rte_smp_wmb();
desc->flags = 0;
desc = &descs[(head_idx++) & (vq->size - 1)];
@@ -1068,11 +1069,11 @@ dequeue_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
/* This desc reaches to its end, get the next one */
if (desc_avail == 0) {
+ if ((desc->flags & VRING_DESC_F_NEXT) == 0)
+ break;
+
+ rte_smp_wmb();
desc->flags = 0;
-
- if ((desc->flags & VRING_DESC_F_NEXT) == 0)
- break;
-
desc = &descs[(head_idx++) & (vq->size - 1)];
if (unlikely(desc->flags & VRING_DESC_F_INDIRECT))
return -1;
@@ -1111,6 +1112,7 @@ dequeue_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
mbuf_avail = cur->buf_len - RTE_PKTMBUF_HEADROOM;
}
}
+ rte_smp_wmb();
desc->flags = 0;
prev->data_len = mbuf_offset;
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 08/29] xxx: batch the desc_hw update?
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (6 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 07/29] vhost: mark desc being used Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 09/29] xxx: virtio: remove overheads Tiwei Bie
` (20 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
drivers/net/virtio/virtio_rxtx_1.1.c | 18 ++++++++++--------
lib/librte_vhost/virtio_net.c | 17 ++++++++++-------
2 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/drivers/net/virtio/virtio_rxtx_1.1.c b/drivers/net/virtio/virtio_rxtx_1.1.c
index e47a346..05f9dc7 100644
--- a/drivers/net/virtio/virtio_rxtx_1.1.c
+++ b/drivers/net/virtio/virtio_rxtx_1.1.c
@@ -89,7 +89,7 @@ virtio_xmit_cleanup(struct virtqueue *vq)
}
static inline void
-virtio_xmit(struct virtnet_tx *txvq, struct rte_mbuf *mbuf)
+virtio_xmit(struct virtnet_tx *txvq, struct rte_mbuf *mbuf, int first_mbuf)
{
struct virtio_tx_region *txr = txvq->virtio_net_hdr_mz->addr;
struct virtqueue *vq = txvq->vq;
@@ -105,6 +105,8 @@ virtio_xmit(struct virtnet_tx *txvq, struct rte_mbuf *mbuf)
RTE_PTR_DIFF(&txr[idx].tx_hdr, txr);
desc[idx].len = vq->hw->vtnet_hdr_size;
desc[idx].flags = VRING_DESC_F_NEXT;
+ if (!first_mbuf)
+ desc[idx].flags |= DESC_HW;
do {
idx = (vq->vq_avail_idx++) & (vq->vq_nentries - 1);
@@ -115,12 +117,6 @@ virtio_xmit(struct virtnet_tx *txvq, struct rte_mbuf *mbuf)
desc[idx].flags &= ~VRING_DESC_F_NEXT;
- /*
- * update the head last, so that when the host saw such flag
- * is set, it means all others in the same chain is also set
- */
- rte_smp_wmb();
- desc[head_idx].flags |= DESC_HW;
}
uint16_t
@@ -129,6 +125,7 @@ virtio_xmit_pkts_1_1(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts
struct virtnet_tx *txvq = tx_queue;
struct virtqueue *vq = txvq->vq;
uint16_t i;
+ uint16_t head_idx = vq->vq_avail_idx;
if (unlikely(nb_pkts < 1))
return nb_pkts;
@@ -148,10 +145,15 @@ virtio_xmit_pkts_1_1(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts
}
}
- virtio_xmit(txvq, txm);
+ virtio_xmit(txvq, txm, i == 0);
txvq->stats.bytes += txm->pkt_len;
}
+ if (likely(i)) {
+ rte_smp_wmb();
+ vq->vq_ring.desc_1_1[head_idx & (vq->vq_nentries - 1)].flags |= DESC_HW;
+ }
+
txvq->stats.packets += i;
txvq->stats.errors += nb_pkts - i;
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index df88e31..c9e466f 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -1009,9 +1009,6 @@ dequeue_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
*/
if (likely((desc->len == dev->vhost_hlen) &&
(desc->flags & VRING_DESC_F_NEXT) != 0)) {
- rte_smp_wmb();
- desc->flags = 0;
-
desc = &descs[(head_idx++) & (vq->size - 1)];
if (unlikely(desc->flags & VRING_DESC_F_INDIRECT))
return -1;
@@ -1072,8 +1069,6 @@ dequeue_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
if ((desc->flags & VRING_DESC_F_NEXT) == 0)
break;
- rte_smp_wmb();
- desc->flags = 0;
desc = &descs[(head_idx++) & (vq->size - 1)];
if (unlikely(desc->flags & VRING_DESC_F_INDIRECT))
return -1;
@@ -1112,8 +1107,6 @@ dequeue_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
mbuf_avail = cur->buf_len - RTE_PKTMBUF_HEADROOM;
}
}
- rte_smp_wmb();
- desc->flags = 0;
prev->data_len = mbuf_offset;
m->pkt_len += mbuf_offset;
@@ -1134,7 +1127,9 @@ vhost_dequeue_burst_1_1(struct virtio_net *dev, struct vhost_virtqueue *vq,
uint16_t i;
uint16_t idx;
struct vring_desc_1_1 *desc = vq->desc_1_1;
+ uint16_t head_idx = vq->last_used_idx;
+ count = RTE_MIN(MAX_PKT_BURST, count);
for (i = 0; i < count; i++) {
idx = vq->last_used_idx & (vq->size - 1);
if (!(desc[idx].flags & DESC_HW))
@@ -1150,6 +1145,14 @@ vhost_dequeue_burst_1_1(struct virtio_net *dev, struct vhost_virtqueue *vq,
dequeue_desc(dev, vq, mbuf_pool, pkts[i], desc);
}
+ if (likely(i)) {
+ for (idx = 1; idx < (uint16_t)(vq->last_used_idx - head_idx); idx++) {
+ desc[(idx + head_idx) & (vq->size - 1)].flags = 0;
+ }
+ rte_smp_wmb();
+ desc[head_idx & (vq->size - 1)].flags = 0;
+ }
+
return i;
}
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 09/29] xxx: virtio: remove overheads
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (7 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 08/29] xxx: batch the desc_hw update? Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 10/29] vhost: prefetch desc Tiwei Bie
` (19 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
for better performance comparing
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
drivers/net/virtio/virtio_rxtx.c | 190 +++------------------------------------
1 file changed, 13 insertions(+), 177 deletions(-)
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index e697192..c49ac0d 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -218,76 +218,16 @@ virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct rte_mbuf *cookie)
return 0;
}
-/* When doing TSO, the IP length is not included in the pseudo header
- * checksum of the packet given to the PMD, but for virtio it is
- * expected.
- */
-static void
-virtio_tso_fix_cksum(struct rte_mbuf *m)
-{
- /* common case: header is not fragmented */
- if (likely(rte_pktmbuf_data_len(m) >= m->l2_len + m->l3_len +
- m->l4_len)) {
- struct ipv4_hdr *iph;
- struct ipv6_hdr *ip6h;
- struct tcp_hdr *th;
- uint16_t prev_cksum, new_cksum, ip_len, ip_paylen;
- uint32_t tmp;
-
- iph = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *, m->l2_len);
- th = RTE_PTR_ADD(iph, m->l3_len);
- if ((iph->version_ihl >> 4) == 4) {
- iph->hdr_checksum = 0;
- iph->hdr_checksum = rte_ipv4_cksum(iph);
- ip_len = iph->total_length;
- ip_paylen = rte_cpu_to_be_16(rte_be_to_cpu_16(ip_len) -
- m->l3_len);
- } else {
- ip6h = (struct ipv6_hdr *)iph;
- ip_paylen = ip6h->payload_len;
- }
-
- /* calculate the new phdr checksum not including ip_paylen */
- prev_cksum = th->cksum;
- tmp = prev_cksum;
- tmp += ip_paylen;
- tmp = (tmp & 0xffff) + (tmp >> 16);
- new_cksum = tmp;
-
- /* replace it in the packet */
- th->cksum = new_cksum;
- }
-}
-
-static inline int
-tx_offload_enabled(struct virtio_hw *hw)
-{
- return vtpci_with_feature(hw, VIRTIO_NET_F_CSUM) ||
- vtpci_with_feature(hw, VIRTIO_NET_F_HOST_TSO4) ||
- vtpci_with_feature(hw, VIRTIO_NET_F_HOST_TSO6);
-}
-
-/* avoid write operation when necessary, to lessen cache issues */
-#define ASSIGN_UNLESS_EQUAL(var, val) do { \
- if ((var) != (val)) \
- (var) = (val); \
-} while (0)
-
static inline void
virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
- uint16_t needed, int use_indirect, int can_push)
+ uint16_t needed)
{
struct virtio_tx_region *txr = txvq->virtio_net_hdr_mz->addr;
struct vq_desc_extra *dxp;
struct virtqueue *vq = txvq->vq;
struct vring_desc *start_dp;
- uint16_t seg_num = cookie->nb_segs;
uint16_t head_idx, idx;
- uint16_t head_size = vq->hw->vtnet_hdr_size;
- struct virtio_net_hdr *hdr;
- int offload;
- offload = tx_offload_enabled(vq->hw);
head_idx = vq->vq_desc_head_idx;
idx = head_idx;
dxp = &vq->vq_descx[idx];
@@ -296,91 +236,15 @@ virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
start_dp = vq->vq_ring.desc;
- if (can_push) {
- /* prepend cannot fail, checked by caller */
- hdr = (struct virtio_net_hdr *)
- rte_pktmbuf_prepend(cookie, head_size);
- /* if offload disabled, it is not zeroed below, do it now */
- if (offload == 0) {
- ASSIGN_UNLESS_EQUAL(hdr->csum_start, 0);
- ASSIGN_UNLESS_EQUAL(hdr->csum_offset, 0);
- ASSIGN_UNLESS_EQUAL(hdr->flags, 0);
- ASSIGN_UNLESS_EQUAL(hdr->gso_type, 0);
- ASSIGN_UNLESS_EQUAL(hdr->gso_size, 0);
- ASSIGN_UNLESS_EQUAL(hdr->hdr_len, 0);
- }
- } else if (use_indirect) {
- /* setup tx ring slot to point to indirect
- * descriptor list stored in reserved region.
- *
- * the first slot in indirect ring is already preset
- * to point to the header in reserved region
- */
- start_dp[idx].addr = txvq->virtio_net_hdr_mem +
- RTE_PTR_DIFF(&txr[idx].tx_indir, txr);
- start_dp[idx].len = (seg_num + 1) * sizeof(struct vring_desc);
- start_dp[idx].flags = VRING_DESC_F_INDIRECT;
- hdr = (struct virtio_net_hdr *)&txr[idx].tx_hdr;
-
- /* loop below will fill in rest of the indirect elements */
- start_dp = txr[idx].tx_indir;
- idx = 1;
- } else {
- /* setup first tx ring slot to point to header
- * stored in reserved region.
- */
- start_dp[idx].addr = txvq->virtio_net_hdr_mem +
- RTE_PTR_DIFF(&txr[idx].tx_hdr, txr);
- start_dp[idx].len = vq->hw->vtnet_hdr_size;
- start_dp[idx].flags = VRING_DESC_F_NEXT;
- hdr = (struct virtio_net_hdr *)&txr[idx].tx_hdr;
-
- idx = start_dp[idx].next;
- }
-
- /* Checksum Offload / TSO */
- if (offload) {
- if (cookie->ol_flags & PKT_TX_TCP_SEG)
- cookie->ol_flags |= PKT_TX_TCP_CKSUM;
-
- switch (cookie->ol_flags & PKT_TX_L4_MASK) {
- case PKT_TX_UDP_CKSUM:
- hdr->csum_start = cookie->l2_len + cookie->l3_len;
- hdr->csum_offset = offsetof(struct udp_hdr,
- dgram_cksum);
- hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
- break;
-
- case PKT_TX_TCP_CKSUM:
- hdr->csum_start = cookie->l2_len + cookie->l3_len;
- hdr->csum_offset = offsetof(struct tcp_hdr, cksum);
- hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
- break;
-
- default:
- ASSIGN_UNLESS_EQUAL(hdr->csum_start, 0);
- ASSIGN_UNLESS_EQUAL(hdr->csum_offset, 0);
- ASSIGN_UNLESS_EQUAL(hdr->flags, 0);
- break;
- }
-
- /* TCP Segmentation Offload */
- if (cookie->ol_flags & PKT_TX_TCP_SEG) {
- virtio_tso_fix_cksum(cookie);
- hdr->gso_type = (cookie->ol_flags & PKT_TX_IPV6) ?
- VIRTIO_NET_HDR_GSO_TCPV6 :
- VIRTIO_NET_HDR_GSO_TCPV4;
- hdr->gso_size = cookie->tso_segsz;
- hdr->hdr_len =
- cookie->l2_len +
- cookie->l3_len +
- cookie->l4_len;
- } else {
- ASSIGN_UNLESS_EQUAL(hdr->gso_type, 0);
- ASSIGN_UNLESS_EQUAL(hdr->gso_size, 0);
- ASSIGN_UNLESS_EQUAL(hdr->hdr_len, 0);
- }
- }
+ /* setup first tx ring slot to point to header
+ * stored in reserved region.
+ */
+ start_dp[idx].addr = txvq->virtio_net_hdr_mem +
+ RTE_PTR_DIFF(&txr[idx].tx_hdr, txr);
+ start_dp[idx].len = vq->hw->vtnet_hdr_size;
+ start_dp[idx].flags = VRING_DESC_F_NEXT;
+
+ idx = start_dp[idx].next;
do {
start_dp[idx].addr = VIRTIO_MBUF_DATA_DMA_ADDR(cookie, vq);
@@ -389,9 +253,6 @@ virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
idx = start_dp[idx].next;
} while ((cookie = cookie->next) != NULL);
- if (use_indirect)
- idx = vq->vq_ring.desc[head_idx].next;
-
vq->vq_desc_head_idx = idx;
if (vq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END)
vq->vq_desc_tail_idx = idx;
@@ -1011,9 +872,7 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
struct virtnet_tx *txvq = tx_queue;
struct virtqueue *vq = txvq->vq;
struct virtio_hw *hw = vq->hw;
- uint16_t hdr_size = hw->vtnet_hdr_size;
uint16_t nb_used, nb_tx = 0;
- int error;
if (unlikely(hw->started == 0))
return nb_tx;
@@ -1030,37 +889,14 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
struct rte_mbuf *txm = tx_pkts[nb_tx];
- int can_push = 0, use_indirect = 0, slots, need;
-
- /* Do VLAN tag insertion */
- if (unlikely(txm->ol_flags & PKT_TX_VLAN_PKT)) {
- error = rte_vlan_insert(&txm);
- if (unlikely(error)) {
- rte_pktmbuf_free(txm);
- continue;
- }
- }
-
- /* 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 &&
- rte_is_aligned(rte_pktmbuf_mtod(txm, char *),
- __alignof__(struct virtio_net_hdr_mrg_rxbuf)))
- can_push = 1;
- else if (vtpci_with_feature(hw, VIRTIO_RING_F_INDIRECT_DESC) &&
- txm->nb_segs < VIRTIO_MAX_TX_INDIRECT)
- use_indirect = 1;
+ int slots, need;
/* How many main ring entries are needed to this Tx?
* any_layout => number of segments
* indirect => 1
* default => number of segments + 1
*/
- slots = use_indirect ? 1 : (txm->nb_segs + !can_push);
+ slots =txm->nb_segs + 1;
need = slots - vq->vq_free_cnt;
/* Positive value indicates it need free vring descriptors */
@@ -1079,7 +915,7 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
}
/* Enqueue Packet buffers */
- virtqueue_enqueue_xmit(txvq, txm, slots, use_indirect, can_push);
+ virtqueue_enqueue_xmit(txvq, txm, slots);
txvq->stats.bytes += txm->pkt_len;
virtio_update_packet_stats(&txvq->stats, txm);
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 10/29] vhost: prefetch desc
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (8 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 09/29] xxx: virtio: remove overheads Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 11/29] add virtio 1.1 test guide Tiwei Bie
` (18 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
lib/librte_vhost/virtio_net.c | 36 +++++++++++++++++++++++++++++-------
1 file changed, 29 insertions(+), 7 deletions(-)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index c9e466f..b4d9031 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -974,10 +974,10 @@ mbuf_is_consumed(struct rte_mbuf *m)
return true;
}
-static inline uint16_t
+static inline uint16_t __attribute__((always_inline))
dequeue_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
struct rte_mempool *mbuf_pool, struct rte_mbuf *m,
- struct vring_desc_1_1 *descs)
+ struct vring_desc_1_1 *descs, uint16_t *desc_idx)
{
struct vring_desc_1_1 *desc;
uint64_t desc_addr;
@@ -986,7 +986,7 @@ dequeue_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
uint32_t cpy_len;
struct rte_mbuf *cur = m, *prev = m;
struct virtio_net_hdr *hdr = NULL;
- uint16_t head_idx = vq->last_used_idx;
+ uint16_t head_idx = *desc_idx;
desc = &descs[(head_idx++) & (vq->size - 1)];
if (unlikely((desc->len < dev->vhost_hlen)) ||
@@ -1114,7 +1114,7 @@ dequeue_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
if (hdr)
vhost_dequeue_offload(hdr, m);
- vq->last_used_idx = head_idx;
+ *desc_idx = head_idx;
return 0;
}
@@ -1128,11 +1128,32 @@ vhost_dequeue_burst_1_1(struct virtio_net *dev, struct vhost_virtqueue *vq,
uint16_t idx;
struct vring_desc_1_1 *desc = vq->desc_1_1;
uint16_t head_idx = vq->last_used_idx;
+ struct vring_desc_1_1 desc_cached[64];
+ uint16_t desc_idx = 0;
+
+ idx = vq->last_used_idx & (vq->size - 1);
+ if (!(desc[idx].flags & DESC_HW))
+ return 0;
count = RTE_MIN(MAX_PKT_BURST, count);
+
+ {
+ uint16_t size = vq->size - idx;
+ if (size >= 64)
+ rte_memcpy(&desc_cached[0], &desc[idx], 64 * sizeof(struct vring_desc_1_1));
+ else {
+ rte_memcpy(&desc_cached[0], &desc[idx], size * sizeof(struct vring_desc_1_1));
+ rte_memcpy(&desc_cached[size], &desc[0], (64 - size) * sizeof(struct vring_desc_1_1));
+ }
+ }
+
+ //for (i = 0; i < 64; i++) {
+ // idx = (vq->last_used_idx + i) & (vq->size - 1);
+ // desc_cached[i] = desc[idx];
+ //}
+
for (i = 0; i < count; i++) {
- idx = vq->last_used_idx & (vq->size - 1);
- if (!(desc[idx].flags & DESC_HW))
+ if (!(desc_cached[desc_idx].flags & DESC_HW))
break;
pkts[i] = rte_pktmbuf_alloc(mbuf_pool);
@@ -1142,9 +1163,10 @@ vhost_dequeue_burst_1_1(struct virtio_net *dev, struct vhost_virtqueue *vq,
break;
}
- dequeue_desc(dev, vq, mbuf_pool, pkts[i], desc);
+ dequeue_desc(dev, vq, mbuf_pool, pkts[i], desc_cached, &desc_idx);
}
+ vq->last_used_idx += desc_idx;
if (likely(i)) {
for (idx = 1; idx < (uint16_t)(vq->last_used_idx - head_idx); idx++) {
desc[(idx + head_idx) & (vq->size - 1)].flags = 0;
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 11/29] add virtio 1.1 test guide
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (9 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 10/29] vhost: prefetch desc Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 12/29] testpmd: add s-txonly Tiwei Bie
` (17 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
README-virtio-1.1 | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
create mode 100644 README-virtio-1.1
diff --git a/README-virtio-1.1 b/README-virtio-1.1
new file mode 100644
index 0000000..8af3eb3
--- /dev/null
+++ b/README-virtio-1.1
@@ -0,0 +1,50 @@
+This branch implements a very rough virtio 1.1 prototpye: only the Tx path has
+been implemented. And below are the test scripts and guidelines for testing:
+
+- build DPDK
+
+ $ export RTE_SDK=/path/to/dpdk/src
+ $ export RTE_TARGET=x86_64-native-linuxapp-gcc
+ $ make install T=$RTE_TARGET
+
+- run host.sh
+
+- run virtio-user.sh
+ execute 'start' inside the pmd
+ execute 'show port stats all' (2 or more times) to see the throughtput.
+
+Note: both scripts should run on the same machine.
+
+You could also set "version_1_1=0" at virtio-user.sh to test
+the difference between virtio 1.1 and virtio 0.95/1.0.
+
+---
+[yliu@yliu-dev ~]$ cat /tmp/host.sh
+#!/bin/bash
+
+[ "$gdb" ] && gdb="gdb --args"
+
+rm -f vhost-net
+
+sudo $gdb $RTE_SDK/x86_64-native-linuxapp-gcc/app/testpmd \
+ -c 0x5 -n 4 --socket-mem 2048,0 \
+ --no-pci --file-prefix=vhost \
+ --vdev 'net_vhost0,iface=/tmp/vhost-net' \
+ -- \
+ --forward-mode=rxonly \
+ #-i
+
+
+[yliu@yliu-dev ~]$ cat /tmp/virtio-user.sh
+#!/bin/bash
+
+[ "$gdb" ] && gdb="gdb --args"
+
+sudo $gdb $RTE_SDK/x86_64-native-linuxapp-gcc/app/testpmd \
+ -c 0x9 -n 4 --socket-mem 2048,0 \
+ --no-pci --file-prefix=virtio \
+ --vdev=net_virtio_user0,mac=52:54:00:00:00:15,path=/tmp/vhost-net,version_1_1=1 \
+ -- \
+ --forward-mode=txonly \
+ --disable-hw-vlan --no-flush-rx \
+ -i
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 12/29] testpmd: add s-txonly
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (10 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 11/29] add virtio 1.1 test guide Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 13/29] net/virtio: implement the Rx code path Tiwei Bie
` (16 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
app/test-pmd/Makefile | 1 +
app/test-pmd/s-txonly.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++
app/test-pmd/testpmd.c | 1 +
app/test-pmd/testpmd.h | 1 +
4 files changed, 137 insertions(+)
create mode 100644 app/test-pmd/s-txonly.c
diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index 35ecee9..d87cae6 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -55,6 +55,7 @@ SRCS-y += macswap.c
SRCS-y += flowgen.c
SRCS-y += rxonly.c
SRCS-y += txonly.c
+SRCS-y += s-txonly.c
SRCS-y += csumonly.c
SRCS-y += icmpecho.c
SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c
diff --git a/app/test-pmd/s-txonly.c b/app/test-pmd/s-txonly.c
new file mode 100644
index 0000000..6275136
--- /dev/null
+++ b/app/test-pmd/s-txonly.c
@@ -0,0 +1,134 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <assert.h>
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_memcpy.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_ether.h>
+#include <rte_ethdev.h>
+#include <rte_ip.h>
+#include <rte_tcp.h>
+#include <rte_udp.h>
+#include <rte_string_fns.h>
+#include <rte_flow.h>
+
+#include "testpmd.h"
+
+#undef MAX_PKT_BURST
+#define MAX_PKT_BURST 32
+
+/*
+ * Transmit a burst of multi-segments packets.
+ */
+static void
+pkt_burst_transmit(struct fwd_stream *fs)
+{
+ static struct rte_mbuf *pkts[MAX_PKT_BURST];
+ uint16_t nb_tx;
+ int i;
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ uint64_t start_tsc;
+ uint64_t end_tsc;
+ uint64_t core_cycles;
+#endif
+
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ start_tsc = rte_rdtsc();
+#endif
+
+ for (i = 0; i < MAX_PKT_BURST; i++) {
+ if (unlikely(!pkts[i])) {
+ pkts[i] = rte_pktmbuf_alloc(current_fwd_lcore()->mbp);
+ assert(pkts[i]);
+
+ pkts[i]->data_len = tx_pkt_seg_lengths[0];
+ pkts[i]->pkt_len = tx_pkt_seg_lengths[0];
+ pkts[i]->nb_segs = 1;
+ }
+
+ rte_pktmbuf_refcnt_update(pkts[i], 1);
+ }
+
+ nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts, MAX_PKT_BURST);
+
+ //uint32_t retry;
+ //if (unlikely(nb_tx < MAX_PKT_BURST) && fs->retry_enabled) {
+ // retry = 0;
+ // while (nb_tx < MAX_PKT_BURST && retry++ < burst_tx_retry_num) {
+ // rte_delay_us(burst_tx_delay_time);
+ // nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue,
+ // &pkts[nb_tx], MAX_PKT_BURST - nb_tx);
+ // }
+ //}
+
+ fs->tx_packets += nb_tx;
+
+#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
+ end_tsc = rte_rdtsc();
+ core_cycles = (end_tsc - start_tsc);
+ fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
+#endif
+}
+
+struct fwd_engine s_tx_only_engine = {
+ .fwd_mode_name = "s-txonly",
+ .port_fwd_begin = NULL,
+ .port_fwd_end = NULL,
+ .packet_fwd = pkt_burst_transmit,
+};
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index d1041af..f224357 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -160,6 +160,7 @@ struct fwd_engine * fwd_engines[] = {
&flow_gen_engine,
&rx_only_engine,
&tx_only_engine,
+ &s_tx_only_engine,
&csum_fwd_engine,
&icmp_echo_engine,
#ifdef RTE_LIBRTE_IEEE1588
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index e6c43ba..b53ce0a 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -248,6 +248,7 @@ extern struct fwd_engine mac_swap_engine;
extern struct fwd_engine flow_gen_engine;
extern struct fwd_engine rx_only_engine;
extern struct fwd_engine tx_only_engine;
+extern struct fwd_engine s_tx_only_engine;
extern struct fwd_engine csum_fwd_engine;
extern struct fwd_engine icmp_echo_engine;
#ifdef RTE_LIBRTE_IEEE1588
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 13/29] net/virtio: implement the Rx code path
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (11 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 12/29] testpmd: add s-txonly Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 14/29] vhost: a rough implementation on enqueue " Tiwei Bie
` (15 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Just make it stick to the non-mergeable code path now, though it's likely
it would be really easy to add such support.
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
drivers/net/virtio/virtio_ethdev.c | 5 +-
drivers/net/virtio/virtio_rxtx.c | 121 ++++++++++++++++++++++++++++++++++---
drivers/net/virtio/virtqueue.h | 1 +
3 files changed, 116 insertions(+), 11 deletions(-)
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 35ce07d..8b754ac 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1241,7 +1241,7 @@ static void
rx_func_get(struct rte_eth_dev *eth_dev)
{
struct virtio_hw *hw = eth_dev->data->dev_private;
- if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF))
+ if (0 && vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF))
eth_dev->rx_pkt_burst = &virtio_recv_mergeable_pkts;
else
eth_dev->rx_pkt_burst = &virtio_recv_pkts;
@@ -1373,7 +1373,8 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
/* Setting up rx_header size for the device */
if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF) ||
- vtpci_with_feature(hw, VIRTIO_F_VERSION_1))
+ vtpci_with_feature(hw, VIRTIO_F_VERSION_1) ||
+ vtpci_with_feature(hw, VIRTIO_F_VERSION_1_1))
hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);
else
hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr);
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index c49ac0d..3be64da 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -115,8 +115,8 @@ vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
dp->next = VQ_RING_DESC_CHAIN_END;
}
-static uint16_t
-virtqueue_dequeue_burst_rx(struct virtqueue *vq, struct rte_mbuf **rx_pkts,
+static inline uint16_t
+virtqueue_dequeue_burst_rx_1_0(struct virtqueue *vq, struct rte_mbuf **rx_pkts,
uint32_t *len, uint16_t num)
{
struct vring_used_elem *uep;
@@ -149,6 +149,51 @@ virtqueue_dequeue_burst_rx(struct virtqueue *vq, struct rte_mbuf **rx_pkts,
return i;
}
+static inline uint16_t
+virtqueue_dequeue_burst_rx_1_1(struct virtqueue *vq, struct rte_mbuf **rx_pkts,
+ uint32_t *len, uint16_t num)
+{
+ struct vring_desc_1_1 *desc = vq->vq_ring.desc_1_1;
+ struct rte_mbuf *cookie;
+ uint16_t used_idx;
+ uint16_t i;
+
+ for (i = 0; i < num ; i++) {
+ used_idx = (uint16_t)(vq->vq_used_cons_idx & (vq->vq_nentries - 1));
+ if ((desc[used_idx].flags & DESC_HW))
+ break;
+
+ len[i] = desc[used_idx].len;
+ cookie = vq->vq_descx[used_idx].cookie;
+
+ if (unlikely(cookie == NULL)) {
+ PMD_DRV_LOG(ERR, "vring descriptor with no mbuf cookie at %u\n",
+ vq->vq_used_cons_idx);
+ break;
+ }
+ vq->vq_descx[used_idx].cookie = NULL;
+
+ rte_prefetch0(cookie);
+ rte_packet_prefetch(rte_pktmbuf_mtod(cookie, void *));
+ rx_pkts[i] = cookie;
+
+ vq->vq_used_cons_idx++;
+ vq->vq_free_cnt++;
+ }
+
+ return i;
+}
+
+static inline uint16_t
+virtqueue_dequeue_burst_rx(struct virtqueue *vq, struct rte_mbuf **rx_pkts,
+ uint32_t *len, uint16_t num)
+{
+ if (vtpci_version_1_1(vq->hw))
+ return virtqueue_dequeue_burst_rx_1_1(vq, rx_pkts, len, num);
+ else
+ return virtqueue_dequeue_burst_rx_1_0(vq, rx_pkts, len, num);
+}
+
#ifndef DEFAULT_TX_FREE_THRESH
#define DEFAULT_TX_FREE_THRESH 32
#endif
@@ -179,7 +224,7 @@ virtio_xmit_cleanup(struct virtqueue *vq, uint16_t num)
static inline int
-virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct rte_mbuf *cookie)
+virtqueue_enqueue_recv_refill_1_0(struct virtqueue *vq, struct rte_mbuf *cookie)
{
struct vq_desc_extra *dxp;
struct virtio_hw *hw = vq->hw;
@@ -218,6 +263,53 @@ virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct rte_mbuf *cookie)
return 0;
}
+static inline int
+virtqueue_enqueue_recv_refill_1_1(struct virtqueue *vq, struct rte_mbuf *cookie)
+{
+ struct vq_desc_extra *dxp;
+ struct virtio_hw *hw = vq->hw;
+ uint16_t needed = 1;
+ uint16_t idx;
+ struct vring_desc_1_1 *desc = vq->vq_ring.desc_1_1;
+
+ if (unlikely(vq->vq_free_cnt == 0))
+ return -ENOSPC;
+ if (unlikely(vq->vq_free_cnt < needed))
+ return -EMSGSIZE;
+
+ idx = vq->vq_desc_head_idx & (vq->vq_nentries - 1);
+ if (unlikely(desc[idx].flags & DESC_HW))
+ return -EFAULT;
+
+ dxp = &vq->vq_descx[idx];
+ dxp->cookie = cookie;
+ dxp->ndescs = needed;
+
+ desc[idx].addr =
+ VIRTIO_MBUF_ADDR(cookie, vq) +
+ RTE_PKTMBUF_HEADROOM - hw->vtnet_hdr_size;
+ desc[idx].len =
+ cookie->buf_len - RTE_PKTMBUF_HEADROOM + hw->vtnet_hdr_size;
+ desc[idx].flags = VRING_DESC_F_WRITE;
+ vq->vq_desc_head_idx++;
+
+ vq->vq_free_cnt -= needed;
+
+ rte_smp_wmb();
+ desc[idx].flags |= DESC_HW;
+
+ return 0;
+}
+
+static inline int
+virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct rte_mbuf *cookie)
+{
+ if (vtpci_version_1_1(vq->hw))
+ return virtqueue_enqueue_recv_refill_1_1(vq, cookie);
+ else
+ return virtqueue_enqueue_recv_refill_1_0(vq, cookie);
+}
+
static inline void
virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
uint16_t needed)
@@ -288,9 +380,6 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
PMD_INIT_FUNC_TRACE();
- if (vtpci_version_1_1(hw))
- return 0;
-
if (nb_desc == 0 || nb_desc > vq->vq_nentries)
nb_desc = vq->vq_nentries;
vq->vq_free_cnt = RTE_MIN(vq->vq_free_cnt, nb_desc);
@@ -343,7 +432,8 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
nbufs++;
}
- vq_update_avail_idx(vq);
+ if (!vtpci_version_1_1(hw))
+ vq_update_avail_idx(vq);
PMD_INIT_LOG(DEBUG, "Allocated %d bufs", nbufs);
@@ -368,6 +458,10 @@ virtio_update_rxtx_handler(struct rte_eth_dev *dev,
if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON))
use_simple_rxtx = 1;
#endif
+
+ if (vtpci_version_1_1(hw))
+ use_simple_rxtx = 0;
+
/* Use simple rx/tx func if single segment and no offloads */
if (use_simple_rxtx &&
(tx_conf->txq_flags & VIRTIO_SIMPLE_FLAGS) == VIRTIO_SIMPLE_FLAGS &&
@@ -604,7 +698,16 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
if (unlikely(hw->started == 0))
return nb_rx;
- nb_used = VIRTQUEUE_NUSED(vq);
+ /*
+ * we have no idea to know how many used entries without scanning
+ * the desc for virtio 1.1. Thus, let's simply set nb_used to nb_pkts
+ * and let virtqueue_dequeue_burst_rx() to figure out the real
+ * number.
+ */
+ if (vtpci_version_1_1(hw))
+ nb_used = nb_pkts;
+ else
+ nb_used = VIRTQUEUE_NUSED(vq);
virtio_rmb();
@@ -681,7 +784,7 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
nb_enqueued++;
}
- if (likely(nb_enqueued)) {
+ if (likely(nb_enqueued) && !vtpci_version_1_1(hw)) {
vq_update_avail_idx(vq);
if (unlikely(virtqueue_kick_prepare(vq))) {
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 91d2db7..45f49d7 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -272,6 +272,7 @@ vring_desc_init_1_1(struct vring *vr, int n)
int i;
for (i = 0; i < n; i++) {
struct vring_desc_1_1 *desc = &vr->desc_1_1[i];
+ desc->flags = 0;
desc->index = i;
}
}
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 14/29] vhost: a rough implementation on enqueue code path
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (12 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 13/29] net/virtio: implement the Rx code path Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 15/29] vhost: descriptor length should include vhost header Tiwei Bie
` (14 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
lib/librte_vhost/virtio_net.c | 124 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 123 insertions(+), 1 deletion(-)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index b4d9031..f7dd4eb 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -583,6 +583,126 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
return pkt_idx;
}
+static inline int __attribute__((always_inline))
+enqueue_pkt(struct virtio_net *dev, struct vring_desc_1_1 *descs,
+ uint16_t desc_idx, struct rte_mbuf *m)
+{
+ uint32_t desc_avail, desc_offset;
+ uint32_t mbuf_avail, mbuf_offset;
+ uint32_t cpy_len;
+ struct vring_desc_1_1 *desc;
+ uint64_t desc_addr;
+ struct virtio_net_hdr_mrg_rxbuf *hdr;
+
+ desc = &descs[desc_idx];
+ desc_addr = rte_vhost_gpa_to_vva(dev->mem, desc->addr);
+ /*
+ * Checking of 'desc_addr' placed outside of 'unlikely' macro to avoid
+ * performance issue with some versions of gcc (4.8.4 and 5.3.0) which
+ * otherwise stores offset on the stack instead of in a register.
+ */
+ if (unlikely(desc->len < dev->vhost_hlen) || !desc_addr)
+ return -1;
+
+ rte_prefetch0((void *)(uintptr_t)desc_addr);
+
+ hdr = (struct virtio_net_hdr_mrg_rxbuf *)(uintptr_t)desc_addr;
+ virtio_enqueue_offload(m, &hdr->hdr);
+ vhost_log_write(dev, desc->addr, dev->vhost_hlen);
+ PRINT_PACKET(dev, (uintptr_t)desc_addr, dev->vhost_hlen, 0);
+
+ desc_offset = dev->vhost_hlen;
+ desc_avail = desc->len - dev->vhost_hlen;
+
+ mbuf_avail = rte_pktmbuf_data_len(m);
+ mbuf_offset = 0;
+ while (mbuf_avail != 0 || m->next != NULL) {
+ /* done with current mbuf, fetch next */
+ if (mbuf_avail == 0) {
+ m = m->next;
+
+ mbuf_offset = 0;
+ mbuf_avail = rte_pktmbuf_data_len(m);
+ }
+
+ /* done with current desc buf, fetch next */
+ if (desc_avail == 0) {
+ if ((desc->flags & VRING_DESC_F_NEXT) == 0) {
+ /* Room in vring buffer is not enough */
+ return -1;
+ }
+
+ /** NOTE: we should not come here with current
+ virtio-user implementation **/
+ desc_idx = (desc_idx + 1); // & (vq->size - 1);
+ desc = &descs[desc_idx];
+ if (unlikely(!(desc->flags & DESC_HW)))
+ return -1;
+
+ desc_addr = rte_vhost_gpa_to_vva(dev->mem, desc->addr);
+ if (unlikely(!desc_addr))
+ return -1;
+
+ desc_offset = 0;
+ desc_avail = desc->len;
+ }
+
+ cpy_len = RTE_MIN(desc_avail, mbuf_avail);
+ rte_memcpy((void *)((uintptr_t)(desc_addr + desc_offset)),
+ rte_pktmbuf_mtod_offset(m, void *, mbuf_offset),
+ cpy_len);
+ vhost_log_write(dev, desc->addr + desc_offset, cpy_len);
+ PRINT_PACKET(dev, (uintptr_t)(desc_addr + desc_offset),
+ cpy_len, 0);
+
+ mbuf_avail -= cpy_len;
+ mbuf_offset += cpy_len;
+ desc_avail -= cpy_len;
+ desc_offset += cpy_len;
+ }
+
+ return 0;
+}
+
+static inline uint32_t __attribute__((always_inline))
+vhost_enqueue_burst_1_1(struct virtio_net *dev, uint16_t queue_id,
+ struct rte_mbuf **pkts, uint32_t count)
+{
+ struct vhost_virtqueue *vq;
+ uint16_t i;
+ uint16_t idx;
+ struct vring_desc_1_1 *desc;
+ uint16_t head_idx;
+
+ vq = dev->virtqueue[queue_id];
+ if (unlikely(vq->enabled == 0))
+ return 0;
+
+ head_idx = vq->last_used_idx;
+ desc = vq->desc_1_1;
+ for (i = 0; i < count; i++) {
+ /* XXX: there is an assumption that no desc will be chained */
+ idx = vq->last_used_idx & (vq->size - 1);
+ if (!(desc[idx].flags & DESC_HW))
+ break;
+
+ if (enqueue_pkt(dev, desc, idx, pkts[i]) < 0)
+ break;
+
+ vq->last_used_idx++;
+ }
+ count = i;
+
+ rte_smp_wmb();
+ for (i = 0; i < count; i++) {
+ idx = (head_idx + i) & (vq->size - 1);
+ desc[idx].flags &= ~DESC_HW;
+ desc[idx].len = pkts[i]->pkt_len;
+ }
+
+ return count;
+}
+
uint16_t
rte_vhost_enqueue_burst(int vid, uint16_t queue_id,
struct rte_mbuf **pkts, uint16_t count)
@@ -592,7 +712,9 @@ rte_vhost_enqueue_burst(int vid, uint16_t queue_id,
if (!dev)
return 0;
- if (dev->features & (1 << VIRTIO_NET_F_MRG_RXBUF))
+ if (dev->features & (1ULL << VIRTIO_F_VERSION_1_1))
+ return vhost_enqueue_burst_1_1(dev, queue_id, pkts, count);
+ else if (dev->features & (1 << VIRTIO_NET_F_MRG_RXBUF))
return virtio_dev_merge_rx(dev, queue_id, pkts, count);
else
return virtio_dev_rx(dev, queue_id, pkts, count);
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 15/29] vhost: descriptor length should include vhost header
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (13 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 14/29] vhost: a rough implementation on enqueue " Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 16/29] net/virtio: avoid touching packet data Tiwei Bie
` (13 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev; +Cc: Jens Freimann
From: Jens Freimann <jfreiman@redhat.com>
Signed-off-by: Jens Freimann <jfreiman@redhat.com>
---
lib/librte_vhost/virtio_net.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index f7dd4eb..7a978b9 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -697,7 +697,7 @@ vhost_enqueue_burst_1_1(struct virtio_net *dev, uint16_t queue_id,
for (i = 0; i < count; i++) {
idx = (head_idx + i) & (vq->size - 1);
desc[idx].flags &= ~DESC_HW;
- desc[idx].len = pkts[i]->pkt_len;
+ desc[idx].len = pkts[i]->pkt_len + dev->vhost_hlen;
}
return count;
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 16/29] net/virtio: avoid touching packet data
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (14 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 15/29] vhost: descriptor length should include vhost header Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 17/29] net/virtio: fix virtio1.1 feature negotiation Tiwei Bie
` (12 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev
For performance testing purpose, avoid touching the packet data
when receiving packets.
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
drivers/net/virtio/virtio_rxtx.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 3be64da..93d564f 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -139,7 +139,9 @@ virtqueue_dequeue_burst_rx_1_0(struct virtqueue *vq, struct rte_mbuf **rx_pkts,
}
rte_prefetch0(cookie);
+#if 0
rte_packet_prefetch(rte_pktmbuf_mtod(cookie, void *));
+#endif
rx_pkts[i] = cookie;
vq->vq_used_cons_idx++;
vq_ring_free_chain(vq, desc_idx);
@@ -174,7 +176,9 @@ virtqueue_dequeue_burst_rx_1_1(struct virtqueue *vq, struct rte_mbuf **rx_pkts,
vq->vq_descx[used_idx].cookie = NULL;
rte_prefetch0(cookie);
+#if 0
rte_packet_prefetch(rte_pktmbuf_mtod(cookie, void *));
+#endif
rx_pkts[i] = cookie;
vq->vq_used_cons_idx++;
@@ -568,7 +572,9 @@ static void
virtio_update_packet_stats(struct virtnet_stats *stats, struct rte_mbuf *mbuf)
{
uint32_t s = mbuf->pkt_len;
+#if 0
struct ether_addr *ea;
+#endif
if (s == 64) {
stats->size_bins[1]++;
@@ -587,6 +593,7 @@ virtio_update_packet_stats(struct virtnet_stats *stats, struct rte_mbuf *mbuf)
stats->size_bins[7]++;
}
+#if 0
ea = rte_pktmbuf_mtod(mbuf, struct ether_addr *);
if (is_multicast_ether_addr(ea)) {
if (is_broadcast_ether_addr(ea))
@@ -594,6 +601,7 @@ virtio_update_packet_stats(struct virtnet_stats *stats, struct rte_mbuf *mbuf)
else
stats->multicast++;
}
+#endif
}
/* Optionally fill offload information in structure */
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 17/29] net/virtio: fix virtio1.1 feature negotiation
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (15 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 16/29] net/virtio: avoid touching packet data Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 18/29] net/virtio: the Rx support for virtio1.1 has been added now Tiwei Bie
` (11 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
drivers/net/virtio/virtio_user/virtio_user_dev.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 3ff6a05..e3471d1 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -333,7 +333,8 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
1ULL << VIRTIO_NET_F_GUEST_CSUM | \
1ULL << VIRTIO_NET_F_GUEST_TSO4 | \
1ULL << VIRTIO_NET_F_GUEST_TSO6 | \
- 1ULL << VIRTIO_F_VERSION_1)
+ 1ULL << VIRTIO_F_VERSION_1 | \
+ 1ULL << VIRTIO_F_VERSION_1_1)
int
virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
@@ -368,9 +369,9 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
}
if (version_1_1)
- dev->features |= (1ull << VIRTIO_F_VERSION_1_1);
+ dev->device_features |= (1ull << VIRTIO_F_VERSION_1_1);
else
- dev->features &= ~(1ull << VIRTIO_F_VERSION_1_1);
+ dev->device_features &= ~(1ull << VIRTIO_F_VERSION_1_1);
if (dev->mac_specified)
dev->device_features |= (1ull << VIRTIO_NET_F_MAC);
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 18/29] net/virtio: the Rx support for virtio1.1 has been added now
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (16 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 17/29] net/virtio: fix virtio1.1 feature negotiation Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 19/29] vhost: VIRTIO_NET_F_MRG_RXBUF is not supported for now Tiwei Bie
` (10 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
drivers/net/virtio/virtio_ethdev.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 8b754ac..334c4b8 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1757,10 +1757,6 @@ virtio_dev_start(struct rte_eth_dev *dev)
}
}
- /*no rx support for virtio 1.1 yet*/
- if (vtpci_version_1_1(hw))
- return 0;
-
/*Notify the backend
*Otherwise the tap backend might already stop its queue due to fullness.
*vhost backend will have no chance to be waked up
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 19/29] vhost: VIRTIO_NET_F_MRG_RXBUF is not supported for now
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (17 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 18/29] net/virtio: the Rx support for virtio1.1 has been added now Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 20/29] vhost: fix vring addr setup Tiwei Bie
` (9 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_vhost/vhost.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index f3b7ad5..7976621 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -146,7 +146,7 @@ struct vhost_virtqueue {
#define VHOST_USER_F_PROTOCOL_FEATURES 30
/* Features supported by this builtin vhost-user net driver. */
-#define VIRTIO_NET_SUPPORTED_FEATURES ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | \
+#define VIRTIO_NET_SUPPORTED_FEATURES ( \
(1ULL << VIRTIO_NET_F_CTRL_VQ) | \
(1ULL << VIRTIO_NET_F_CTRL_RX) | \
(1ULL << VIRTIO_NET_F_GUEST_ANNOUNCE) | \
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 20/29] vhost: fix vring addr setup
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (18 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 19/29] vhost: VIRTIO_NET_F_MRG_RXBUF is not supported for now Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 21/29] net/virtio: free mbuf when need to use Tiwei Bie
` (8 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_vhost/vhost.c | 4 ++++
lib/librte_vhost/vhost_user.c | 17 +++++++++++++++--
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 19c5a43..b7bc1ee 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -441,6 +441,10 @@ rte_vhost_enable_guest_notification(int vid, uint16_t queue_id, int enable)
return -1;
}
+ if (dev->features & (1ULL << VIRTIO_F_VERSION_1_1)) {
+ return 0;
+ }
+
dev->virtqueue[queue_id]->used->flags = VRING_USED_F_NO_NOTIFY;
return 0;
}
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 3a2de79..9265dcb 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -342,6 +342,19 @@ vhost_user_set_vring_addr(struct virtio_net *dev, VhostUserMsg *msg)
/* addr->index refers to the queue index. The txq 1, rxq is 0. */
vq = dev->virtqueue[msg->payload.addr.index];
+ if (dev->features & (1ULL << VIRTIO_F_VERSION_1_1)) {
+ vq->desc_1_1 = (struct vring_desc_1_1 *)(uintptr_t)qva_to_vva
+ (dev, msg->payload.addr.desc_user_addr);
+ vq->desc = NULL;
+ vq->avail = NULL;
+ vq->used = NULL;
+ vq->log_guest_addr = 0;
+
+ assert(vq->last_used_idx == 0);
+
+ return 0;
+ }
+
/* The addresses are converted from QEMU virtual to Vhost virtual. */
vq->desc = (struct vring_desc *)(uintptr_t)qva_to_vva(dev,
msg->payload.addr.desc_user_addr);
@@ -351,7 +364,7 @@ vhost_user_set_vring_addr(struct virtio_net *dev, VhostUserMsg *msg)
dev->vid);
return -1;
}
- vq->desc_1_1 = (struct vring_desc_1_1 *)vq->desc;
+ vq->desc_1_1 = NULL;
dev = numa_realloc(dev, msg->payload.addr.index);
vq = dev->virtqueue[msg->payload.addr.index];
@@ -617,7 +630,7 @@ vhost_user_set_mem_table(struct virtio_net *dev, struct VhostUserMsg *pmsg)
static int
vq_is_ready(struct vhost_virtqueue *vq)
{
- return vq && vq->desc &&
+ return vq && (vq->desc || vq->desc_1_1) &&
vq->kickfd != VIRTIO_UNINITIALIZED_EVENTFD &&
vq->callfd != VIRTIO_UNINITIALIZED_EVENTFD;
}
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 21/29] net/virtio: free mbuf when need to use
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (19 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 20/29] vhost: fix vring addr setup Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 22/29] vhost: don't copy descs during Rx Tiwei Bie
` (7 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
drivers/net/virtio/virtio_rxtx_1.1.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/net/virtio/virtio_rxtx_1.1.c b/drivers/net/virtio/virtio_rxtx_1.1.c
index 05f9dc7..fdc7402 100644
--- a/drivers/net/virtio/virtio_rxtx_1.1.c
+++ b/drivers/net/virtio/virtio_rxtx_1.1.c
@@ -72,14 +72,6 @@ virtio_xmit_cleanup(struct virtqueue *vq)
idx = vq->vq_used_cons_idx & (size - 1);
while ((desc[idx].flags & DESC_HW) == 0) {
- struct vq_desc_extra *dxp;
-
- dxp = &vq->vq_descx[idx];
- if (dxp->cookie != NULL) {
- rte_pktmbuf_free(dxp->cookie);
- dxp->cookie = NULL;
- }
-
idx = (++vq->vq_used_cons_idx) & (size - 1);
vq->vq_free_cnt++;
@@ -96,10 +88,15 @@ virtio_xmit(struct virtnet_tx *txvq, struct rte_mbuf *mbuf, int first_mbuf)
struct vring_desc_1_1 *desc = vq->vq_ring.desc_1_1;
uint16_t idx;
uint16_t head_idx = (vq->vq_avail_idx++) & (vq->vq_nentries - 1);
+ struct vq_desc_extra *dxp;
idx = head_idx;
vq->vq_free_cnt -= mbuf->nb_segs + 1;
- vq->vq_descx[idx].cookie = mbuf;
+
+ dxp = &vq->vq_descx[idx];
+ if (dxp->cookie != NULL)
+ rte_pktmbuf_free(dxp->cookie);
+ dxp->cookie = mbuf;
desc[idx].addr = txvq->virtio_net_hdr_mem +
RTE_PTR_DIFF(&txr[idx].tx_hdr, txr);
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 22/29] vhost: don't copy descs during Rx
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (20 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 21/29] net/virtio: free mbuf when need to use Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:57 ` [dpdk-dev] [RFC 23/29] vhost: fix mbuf leak Tiwei Bie
` (6 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_vhost/virtio_net.c | 35 ++++++++++-------------------------
1 file changed, 10 insertions(+), 25 deletions(-)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index 7a978b9..c14582b 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -1247,35 +1247,18 @@ vhost_dequeue_burst_1_1(struct virtio_net *dev, struct vhost_virtqueue *vq,
uint16_t count)
{
uint16_t i;
- uint16_t idx;
struct vring_desc_1_1 *desc = vq->desc_1_1;
uint16_t head_idx = vq->last_used_idx;
- struct vring_desc_1_1 desc_cached[64];
- uint16_t desc_idx = 0;
+ uint16_t desc_idx;
- idx = vq->last_used_idx & (vq->size - 1);
- if (!(desc[idx].flags & DESC_HW))
+ desc_idx = vq->last_used_idx;
+ if (!(desc[desc_idx & (vq->size - 1)].flags & DESC_HW))
return 0;
count = RTE_MIN(MAX_PKT_BURST, count);
- {
- uint16_t size = vq->size - idx;
- if (size >= 64)
- rte_memcpy(&desc_cached[0], &desc[idx], 64 * sizeof(struct vring_desc_1_1));
- else {
- rte_memcpy(&desc_cached[0], &desc[idx], size * sizeof(struct vring_desc_1_1));
- rte_memcpy(&desc_cached[size], &desc[0], (64 - size) * sizeof(struct vring_desc_1_1));
- }
- }
-
- //for (i = 0; i < 64; i++) {
- // idx = (vq->last_used_idx + i) & (vq->size - 1);
- // desc_cached[i] = desc[idx];
- //}
-
for (i = 0; i < count; i++) {
- if (!(desc_cached[desc_idx].flags & DESC_HW))
+ if (!(desc[desc_idx & (vq->size - 1)].flags & DESC_HW))
break;
pkts[i] = rte_pktmbuf_alloc(mbuf_pool);
@@ -1285,13 +1268,15 @@ vhost_dequeue_burst_1_1(struct virtio_net *dev, struct vhost_virtqueue *vq,
break;
}
- dequeue_desc(dev, vq, mbuf_pool, pkts[i], desc_cached, &desc_idx);
+ dequeue_desc(dev, vq, mbuf_pool, pkts[i], desc, &desc_idx);
}
- vq->last_used_idx += desc_idx;
+ vq->last_used_idx = desc_idx;
if (likely(i)) {
- for (idx = 1; idx < (uint16_t)(vq->last_used_idx - head_idx); idx++) {
- desc[(idx + head_idx) & (vq->size - 1)].flags = 0;
+ for (desc_idx = 1;
+ desc_idx < (uint16_t)(vq->last_used_idx - head_idx);
+ desc_idx++) {
+ desc[(desc_idx + head_idx) & (vq->size - 1)].flags = 0;
}
rte_smp_wmb();
desc[head_idx & (vq->size - 1)].flags = 0;
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 23/29] vhost: fix mbuf leak
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (21 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 22/29] vhost: don't copy descs during Rx Tiwei Bie
@ 2017-06-21 2:57 ` Tiwei Bie
2017-06-21 2:58 ` [dpdk-dev] [RFC 24/29] net/virtio: cleanup txd when free count below threshold Tiwei Bie
` (5 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:57 UTC (permalink / raw)
To: dev
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_vhost/virtio_net.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index c14582b..2bd1298 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -1250,6 +1250,7 @@ vhost_dequeue_burst_1_1(struct virtio_net *dev, struct vhost_virtqueue *vq,
struct vring_desc_1_1 *desc = vq->desc_1_1;
uint16_t head_idx = vq->last_used_idx;
uint16_t desc_idx;
+ int err;
desc_idx = vq->last_used_idx;
if (!(desc[desc_idx & (vq->size - 1)].flags & DESC_HW))
@@ -1268,7 +1269,11 @@ vhost_dequeue_burst_1_1(struct virtio_net *dev, struct vhost_virtqueue *vq,
break;
}
- dequeue_desc(dev, vq, mbuf_pool, pkts[i], desc, &desc_idx);
+ err = dequeue_desc(dev, vq, mbuf_pool, pkts[i], desc, &desc_idx);
+ if (unlikely(err)) {
+ rte_pktmbuf_free(pkts[i]);
+ break;
+ }
}
vq->last_used_idx = desc_idx;
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 24/29] net/virtio: cleanup txd when free count below threshold
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (22 preceding siblings ...)
2017-06-21 2:57 ` [dpdk-dev] [RFC 23/29] vhost: fix mbuf leak Tiwei Bie
@ 2017-06-21 2:58 ` Tiwei Bie
2017-06-21 2:58 ` [dpdk-dev] [RFC 25/29] net/virtio: refill descs for vhost in batch Tiwei Bie
` (4 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:58 UTC (permalink / raw)
To: dev
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
drivers/net/virtio/virtio_rxtx_1.1.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/virtio/virtio_rxtx_1.1.c b/drivers/net/virtio/virtio_rxtx_1.1.c
index fdc7402..4602e6d 100644
--- a/drivers/net/virtio/virtio_rxtx_1.1.c
+++ b/drivers/net/virtio/virtio_rxtx_1.1.c
@@ -129,6 +129,9 @@ virtio_xmit_pkts_1_1(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts
PMD_TX_LOG(DEBUG, "%d packets to xmit", nb_pkts);
+ if (likely(vq->vq_free_cnt < vq->vq_free_thresh))
+ virtio_xmit_cleanup(vq);
+
for (i = 0; i < nb_pkts; i++) {
struct rte_mbuf *txm = tx_pkts[i];
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 25/29] net/virtio: refill descs for vhost in batch
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (23 preceding siblings ...)
2017-06-21 2:58 ` [dpdk-dev] [RFC 24/29] net/virtio: cleanup txd when free count below threshold Tiwei Bie
@ 2017-06-21 2:58 ` Tiwei Bie
2017-06-21 2:58 ` [dpdk-dev] [RFC 26/29] vhost: remove dead code Tiwei Bie
` (3 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:58 UTC (permalink / raw)
To: dev
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
drivers/net/virtio/virtio_rxtx.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 93d564f..3dc5eaf 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -299,9 +299,6 @@ virtqueue_enqueue_recv_refill_1_1(struct virtqueue *vq, struct rte_mbuf *cookie)
vq->vq_free_cnt -= needed;
- rte_smp_wmb();
- desc[idx].flags |= DESC_HW;
-
return 0;
}
@@ -381,6 +378,7 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
int error, nbufs;
struct rte_mbuf *m;
uint16_t desc_idx;
+ uint16_t head_idx;
PMD_INIT_FUNC_TRACE();
@@ -418,6 +416,8 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
&rxvq->fake_mbuf;
}
+ head_idx = vq->vq_desc_head_idx;
+
while (!virtqueue_full(vq)) {
m = rte_mbuf_raw_alloc(rxvq->mpool);
if (m == NULL)
@@ -438,6 +438,14 @@ virtio_dev_rx_queue_setup(struct rte_eth_dev *dev,
if (!vtpci_version_1_1(hw))
vq_update_avail_idx(vq);
+ else {
+ struct vring_desc_1_1 *desc = vq->vq_ring.desc_1_1;
+ int i;
+ for (i = 0; i < nbufs; i++) {
+ desc[head_idx & (vq->vq_nentries - 1)].flags |= DESC_HW;
+ head_idx++;
+ }
+ }
PMD_INIT_LOG(DEBUG, "Allocated %d bufs", nbufs);
@@ -701,6 +709,7 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
uint32_t hdr_size;
int offload;
struct virtio_net_hdr *hdr;
+ uint16_t head_idx, idx;
nb_rx = 0;
if (unlikely(hw->started == 0))
@@ -774,8 +783,11 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rxvq->stats.packets += nb_rx;
+ head_idx = vq->vq_desc_head_idx;
+
/* Allocate new mbuf for the used descriptor */
error = ENOSPC;
+ int count = 0;
while (likely(!virtqueue_full(vq))) {
new_mbuf = rte_mbuf_raw_alloc(rxvq->mpool);
if (unlikely(new_mbuf == NULL)) {
@@ -790,9 +802,21 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
break;
}
nb_enqueued++;
+ count++;
}
- if (likely(nb_enqueued) && !vtpci_version_1_1(hw)) {
+ if (vtpci_version_1_1(hw)) {
+ struct vring_desc_1_1 *desc = vq->vq_ring.desc_1_1;
+ if (count > 0) {
+ rte_smp_wmb();
+ idx = head_idx + 1;
+ while (--count) {
+ desc[idx & (vq->vq_nentries - 1)].flags |= DESC_HW;
+ idx++;
+ }
+ desc[head_idx & (vq->vq_nentries - 1)].flags |= DESC_HW;
+ }
+ } else if (likely(nb_enqueued)) {
vq_update_avail_idx(vq);
if (unlikely(virtqueue_kick_prepare(vq))) {
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 26/29] vhost: remove dead code
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (24 preceding siblings ...)
2017-06-21 2:58 ` [dpdk-dev] [RFC 25/29] net/virtio: refill descs for vhost in batch Tiwei Bie
@ 2017-06-21 2:58 ` Tiwei Bie
2017-06-21 2:58 ` [dpdk-dev] [RFC 27/29] vhost: various optimizations for Tx Tiwei Bie
` (2 subsequent siblings)
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:58 UTC (permalink / raw)
To: dev
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_vhost/virtio_net.c | 28 ++++------------------------
1 file changed, 4 insertions(+), 24 deletions(-)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index 2bd1298..049b400 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -1153,33 +1153,13 @@ dequeue_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
mbuf_offset = 0;
mbuf_avail = m->buf_len - RTE_PKTMBUF_HEADROOM;
while (1) {
- uint64_t hpa;
cpy_len = RTE_MIN(desc_avail, mbuf_avail);
- /*
- * A desc buf might across two host physical pages that are
- * not continuous. In such case (gpa_to_hpa returns 0), data
- * will be copied even though zero copy is enabled.
- */
- if (unlikely(dev->dequeue_zero_copy && (hpa = gpa_to_hpa(dev,
- desc->addr + desc_offset, cpy_len)))) {
- cur->data_len = cpy_len;
- cur->data_off = 0;
- cur->buf_addr = (void *)(uintptr_t)desc_addr;
- cur->buf_physaddr = hpa;
-
- /*
- * In zero copy mode, one mbuf can only reference data
- * for one or partial of one desc buff.
- */
- mbuf_avail = cpy_len;
- } else {
- rte_memcpy(rte_pktmbuf_mtod_offset(cur, void *,
- mbuf_offset),
- (void *)((uintptr_t)(desc_addr + desc_offset)),
- cpy_len);
- }
+ rte_memcpy(rte_pktmbuf_mtod_offset(cur, void *,
+ mbuf_offset),
+ (void *)((uintptr_t)(desc_addr + desc_offset)),
+ cpy_len);
mbuf_avail -= cpy_len;
mbuf_offset += cpy_len;
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 27/29] vhost: various optimizations for Tx
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (25 preceding siblings ...)
2017-06-21 2:58 ` [dpdk-dev] [RFC 26/29] vhost: remove dead code Tiwei Bie
@ 2017-06-21 2:58 ` Tiwei Bie
2017-06-21 2:58 ` [dpdk-dev] [RFC 28/29] vhost: make the code more readable Tiwei Bie
2017-06-21 2:58 ` [dpdk-dev] [RFC 29/29] vhost: update and return descs in batch Tiwei Bie
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:58 UTC (permalink / raw)
To: dev
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_vhost/virtio_net.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index 049b400..2d111a3 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -604,6 +604,8 @@ enqueue_pkt(struct virtio_net *dev, struct vring_desc_1_1 *descs,
if (unlikely(desc->len < dev->vhost_hlen) || !desc_addr)
return -1;
+ desc->len = m->pkt_len + dev->vhost_hlen;
+
rte_prefetch0((void *)(uintptr_t)desc_addr);
hdr = (struct virtio_net_hdr_mrg_rxbuf *)(uintptr_t)desc_addr;
@@ -632,6 +634,7 @@ enqueue_pkt(struct virtio_net *dev, struct vring_desc_1_1 *descs,
return -1;
}
+ rte_panic("Shouldn't reach here\n");
/** NOTE: we should not come here with current
virtio-user implementation **/
desc_idx = (desc_idx + 1); // & (vq->size - 1);
@@ -680,6 +683,8 @@ vhost_enqueue_burst_1_1(struct virtio_net *dev, uint16_t queue_id,
head_idx = vq->last_used_idx;
desc = vq->desc_1_1;
+ count = RTE_MIN(count, (uint32_t)MAX_PKT_BURST);
+
for (i = 0; i < count; i++) {
/* XXX: there is an assumption that no desc will be chained */
idx = vq->last_used_idx & (vq->size - 1);
@@ -693,11 +698,12 @@ vhost_enqueue_burst_1_1(struct virtio_net *dev, uint16_t queue_id,
}
count = i;
- rte_smp_wmb();
- for (i = 0; i < count; i++) {
- idx = (head_idx + i) & (vq->size - 1);
- desc[idx].flags &= ~DESC_HW;
- desc[idx].len = pkts[i]->pkt_len + dev->vhost_hlen;
+ if (count) {
+ rte_smp_wmb();
+ for (i = 0; i < count; i++) {
+ idx = (head_idx + i) & (vq->size - 1);
+ desc[idx].flags &= ~DESC_HW;
+ }
}
return count;
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 28/29] vhost: make the code more readable
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (26 preceding siblings ...)
2017-06-21 2:58 ` [dpdk-dev] [RFC 27/29] vhost: various optimizations for Tx Tiwei Bie
@ 2017-06-21 2:58 ` Tiwei Bie
2017-06-21 2:58 ` [dpdk-dev] [RFC 29/29] vhost: update and return descs in batch Tiwei Bie
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:58 UTC (permalink / raw)
To: dev
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_vhost/virtio_net.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index 2d111a3..8344bcb 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -1264,10 +1264,10 @@ vhost_dequeue_burst_1_1(struct virtio_net *dev, struct vhost_virtqueue *vq,
vq->last_used_idx = desc_idx;
if (likely(i)) {
- for (desc_idx = 1;
- desc_idx < (uint16_t)(vq->last_used_idx - head_idx);
+ for (desc_idx = head_idx + 1;
+ desc_idx != vq->last_used_idx;
desc_idx++) {
- desc[(desc_idx + head_idx) & (vq->size - 1)].flags = 0;
+ desc[desc_idx & (vq->size - 1)].flags = 0;
}
rte_smp_wmb();
desc[head_idx & (vq->size - 1)].flags = 0;
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [RFC 29/29] vhost: update and return descs in batch
2017-06-21 2:57 [dpdk-dev] [RFC 00/29] latest virtio1.1 prototype Tiwei Bie
` (27 preceding siblings ...)
2017-06-21 2:58 ` [dpdk-dev] [RFC 28/29] vhost: make the code more readable Tiwei Bie
@ 2017-06-21 2:58 ` Tiwei Bie
28 siblings, 0 replies; 30+ messages in thread
From: Tiwei Bie @ 2017-06-21 2:58 UTC (permalink / raw)
To: dev
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_vhost/virtio_net.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index 8344bcb..7f76b1a 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -604,8 +604,6 @@ enqueue_pkt(struct virtio_net *dev, struct vring_desc_1_1 *descs,
if (unlikely(desc->len < dev->vhost_hlen) || !desc_addr)
return -1;
- desc->len = m->pkt_len + dev->vhost_hlen;
-
rte_prefetch0((void *)(uintptr_t)desc_addr);
hdr = (struct virtio_net_hdr_mrg_rxbuf *)(uintptr_t)desc_addr;
@@ -699,11 +697,15 @@ vhost_enqueue_burst_1_1(struct virtio_net *dev, uint16_t queue_id,
count = i;
if (count) {
- rte_smp_wmb();
- for (i = 0; i < count; i++) {
+ for (i = 1; i < count; i++) {
idx = (head_idx + i) & (vq->size - 1);
+ desc[idx].len = pkts[i]->pkt_len + dev->vhost_hlen;
desc[idx].flags &= ~DESC_HW;
}
+ desc[head_idx & (vq->size - 1)].len =
+ pkts[0]->pkt_len + dev->vhost_hlen;
+ rte_smp_wmb();
+ desc[head_idx & (vq->size - 1)].flags &= ~DESC_HW;
}
return count;
--
2.7.4
^ permalink raw reply [flat|nested] 30+ messages in thread