import dpdk-18.11.2-3.el8
This commit is contained in:
parent
3a7d9efcac
commit
01b2eb7876
@ -1 +1 @@
|
||||
9f538fb3449205bccca93073d79176636134705b SOURCES/dpdk-18.11.tar.xz
|
||||
6e04c3e3a82f91ebe0360b8067df59e2b774924d SOURCES/dpdk-18.11.2.tar.xz
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
SOURCES/dpdk-18.11.tar.xz
|
||||
SOURCES/dpdk-18.11.2.tar.xz
|
||||
|
@ -1,57 +0,0 @@
|
||||
From 25363eb99bc43443bec354abea1e40db61280b30 Mon Sep 17 00:00:00 2001
|
||||
From: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Date: Wed, 5 Dec 2018 14:11:56 -0800
|
||||
Subject: [PATCH 1/3] bus/vmbus: fix race in subchannel creation
|
||||
|
||||
[ upstream commit 4970103e89f4f828669acf3b465e984fdc891e1e ]
|
||||
|
||||
When using multiple queues, there was a race with the kernel
|
||||
in setting up the second channel. This regression is due to a kernel change
|
||||
which does not allow accessing sysfs files for Hyper-V channels that are not opened.
|
||||
|
||||
The fix is simple, just move the logic to detect not ready
|
||||
sub channels earlier in the existing loop.
|
||||
|
||||
Fixes: 831dba47bd36 ("bus/vmbus: add Hyper-V virtual bus support")
|
||||
|
||||
Reported-by: Mohammed Gamal <mgamal@redhat.com>
|
||||
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
(cherry picked from commit ca17e6624251b05cf188997cffc3e1ab2e50561a)
|
||||
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
---
|
||||
drivers/bus/vmbus/linux/vmbus_uio.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/bus/vmbus/linux/vmbus_uio.c b/drivers/bus/vmbus/linux/vmbus_uio.c
|
||||
index 12e97e3a4..38df4d724 100644
|
||||
--- a/drivers/bus/vmbus/linux/vmbus_uio.c
|
||||
+++ b/drivers/bus/vmbus/linux/vmbus_uio.c
|
||||
@@ -357,6 +357,12 @@ int vmbus_uio_get_subchan(struct vmbus_channel *primary,
|
||||
continue;
|
||||
}
|
||||
|
||||
+ if (!vmbus_isnew_subchannel(primary, relid))
|
||||
+ continue; /* Already know about you */
|
||||
+
|
||||
+ if (!vmbus_uio_ring_present(dev, relid))
|
||||
+ continue; /* Ring may not be ready yet */
|
||||
+
|
||||
snprintf(subchan_path, sizeof(subchan_path), "%s/%lu",
|
||||
chan_path, relid);
|
||||
err = vmbus_uio_sysfs_read(subchan_path, "subchannel_id",
|
||||
@@ -370,12 +376,6 @@ int vmbus_uio_get_subchan(struct vmbus_channel *primary,
|
||||
if (subid == 0)
|
||||
continue; /* skip primary channel */
|
||||
|
||||
- if (!vmbus_isnew_subchannel(primary, relid))
|
||||
- continue;
|
||||
-
|
||||
- if (!vmbus_uio_ring_present(dev, relid))
|
||||
- continue; /* Ring may not be ready yet */
|
||||
-
|
||||
err = vmbus_uio_sysfs_read(subchan_path, "monitor_id",
|
||||
&monid, UINT8_MAX);
|
||||
if (err) {
|
||||
--
|
||||
2.20.1
|
||||
|
102
SOURCES/0001-net-virtio-add-packed-virtqueue-defines.patch
Normal file
102
SOURCES/0001-net-virtio-add-packed-virtqueue-defines.patch
Normal file
@ -0,0 +1,102 @@
|
||||
From 93f21370ca38ae61dc2d938adf569f6668381c32 Mon Sep 17 00:00:00 2001
|
||||
From: Jens Freimann <jfreimann@redhat.com>
|
||||
Date: Mon, 17 Dec 2018 22:31:30 +0100
|
||||
Subject: [PATCH 01/18] net/virtio: add packed virtqueue defines
|
||||
|
||||
[ upstream commit 4c3f5822eb21476fbbd807a7c40584c1090695e5 ]
|
||||
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit 4c3f5822eb21476fbbd807a7c40584c1090695e5)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_pci.h | 1 +
|
||||
drivers/net/virtio/virtio_ring.h | 30 ++++++++++++++++++++++++++++++
|
||||
drivers/net/virtio/virtqueue.h | 6 ++++++
|
||||
3 files changed, 37 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
|
||||
index e961a58ca..4c975a531 100644
|
||||
--- a/drivers/net/virtio/virtio_pci.h
|
||||
+++ b/drivers/net/virtio/virtio_pci.h
|
||||
@@ -113,6 +113,7 @@ struct virtnet_ctl;
|
||||
|
||||
#define VIRTIO_F_VERSION_1 32
|
||||
#define VIRTIO_F_IOMMU_PLATFORM 33
|
||||
+#define VIRTIO_F_RING_PACKED 34
|
||||
|
||||
/*
|
||||
* Some VirtIO feature bits (currently bits 28 through 31) are
|
||||
diff --git a/drivers/net/virtio/virtio_ring.h b/drivers/net/virtio/virtio_ring.h
|
||||
index 9e3c2a015..464449074 100644
|
||||
--- a/drivers/net/virtio/virtio_ring.h
|
||||
+++ b/drivers/net/virtio/virtio_ring.h
|
||||
@@ -15,6 +15,10 @@
|
||||
#define VRING_DESC_F_WRITE 2
|
||||
/* This means the buffer contains a list of buffer descriptors. */
|
||||
#define VRING_DESC_F_INDIRECT 4
|
||||
+/* This flag means the descriptor was made available by the driver */
|
||||
+#define VRING_DESC_F_AVAIL(b) ((uint16_t)(b) << 7)
|
||||
+/* This flag means the descriptor was used by the device */
|
||||
+#define VRING_DESC_F_USED(b) ((uint16_t)(b) << 15)
|
||||
|
||||
/* The Host uses this in used->flags to advise the Guest: don't kick me
|
||||
* when you add a buffer. It's unreliable, so it's simply an
|
||||
@@ -54,6 +58,32 @@ struct vring_used {
|
||||
struct vring_used_elem ring[0];
|
||||
};
|
||||
|
||||
+/* For support of packed virtqueues in Virtio 1.1 the format of descriptors
|
||||
+ * looks like this.
|
||||
+ */
|
||||
+struct vring_packed_desc {
|
||||
+ uint64_t addr;
|
||||
+ uint32_t len;
|
||||
+ uint16_t id;
|
||||
+ uint16_t flags;
|
||||
+};
|
||||
+
|
||||
+#define RING_EVENT_FLAGS_ENABLE 0x0
|
||||
+#define RING_EVENT_FLAGS_DISABLE 0x1
|
||||
+#define RING_EVENT_FLAGS_DESC 0x2
|
||||
+struct vring_packed_desc_event {
|
||||
+ uint16_t desc_event_off_wrap;
|
||||
+ uint16_t desc_event_flags;
|
||||
+};
|
||||
+
|
||||
+struct vring_packed {
|
||||
+ unsigned int num;
|
||||
+ struct vring_packed_desc *desc_packed;
|
||||
+ struct vring_packed_desc_event *driver_event;
|
||||
+ struct vring_packed_desc_event *device_event;
|
||||
+
|
||||
+};
|
||||
+
|
||||
struct vring {
|
||||
unsigned int num;
|
||||
struct vring_desc *desc;
|
||||
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
|
||||
index 2e2abf15b..1525c7d10 100644
|
||||
--- a/drivers/net/virtio/virtqueue.h
|
||||
+++ b/drivers/net/virtio/virtqueue.h
|
||||
@@ -161,11 +161,17 @@ struct virtio_pmd_ctrl {
|
||||
struct vq_desc_extra {
|
||||
void *cookie;
|
||||
uint16_t ndescs;
|
||||
+ uint16_t next;
|
||||
};
|
||||
|
||||
struct virtqueue {
|
||||
struct virtio_hw *hw; /**< virtio_hw structure pointer. */
|
||||
struct vring vq_ring; /**< vring keeping desc, used and avail */
|
||||
+ struct vring_packed ring_packed; /**< vring keeping descs */
|
||||
+ bool avail_wrap_counter;
|
||||
+ bool used_wrap_counter;
|
||||
+ uint16_t event_flags_shadow;
|
||||
+ uint16_t avail_used_flags;
|
||||
/**
|
||||
* Last consumed descriptor in the used table,
|
||||
* trails vq_ring.used->idx.
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,78 @@
|
||||
From 8093f82b3e52efe012e46c429b7af4e82492f71c Mon Sep 17 00:00:00 2001
|
||||
From: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
Date: Tue, 27 Nov 2018 11:54:27 +0100
|
||||
Subject: [PATCH] net/virtio: allocate vrings on device NUMA node
|
||||
|
||||
[ upstream commit 4a5140ab17d29e77eefa47b5cb514238e8e0c132 ]
|
||||
|
||||
When a guest is spanned on multiple NUMA nodes and
|
||||
multiple Virtio devices are spanned onto these nodes,
|
||||
we expect that their ring memory is allocated in the
|
||||
right memory node.
|
||||
|
||||
Otherwise, vCPUs from node A may be polling Virtio rings
|
||||
allocated on node B, which would increase QPI bandwidth
|
||||
and impact performance.
|
||||
|
||||
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
Reviewed-by: David Marchand <david.marchand@redhat.com>
|
||||
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_ethdev.c | 12 +++++++-----
|
||||
1 file changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
|
||||
index 2ba66d291..cb2b2e0bf 100644
|
||||
--- a/drivers/net/virtio/virtio_ethdev.c
|
||||
+++ b/drivers/net/virtio/virtio_ethdev.c
|
||||
@@ -335,8 +335,10 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
|
||||
void *sw_ring = NULL;
|
||||
int queue_type = virtio_get_queue_type(hw, vtpci_queue_idx);
|
||||
int ret;
|
||||
+ int numa_node = dev->device->numa_node;
|
||||
|
||||
- PMD_INIT_LOG(DEBUG, "setting up queue: %u", vtpci_queue_idx);
|
||||
+ PMD_INIT_LOG(INFO, "setting up queue: %u on NUMA node %d",
|
||||
+ vtpci_queue_idx, numa_node);
|
||||
|
||||
/*
|
||||
* Read the virtqueue size from the Queue Size field
|
||||
@@ -372,7 +374,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
|
||||
}
|
||||
|
||||
vq = rte_zmalloc_socket(vq_name, size, RTE_CACHE_LINE_SIZE,
|
||||
- SOCKET_ID_ANY);
|
||||
+ numa_node);
|
||||
if (vq == NULL) {
|
||||
PMD_INIT_LOG(ERR, "can not allocate vq");
|
||||
return -ENOMEM;
|
||||
@@ -392,7 +394,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
|
||||
size, vq->vq_ring_size);
|
||||
|
||||
mz = rte_memzone_reserve_aligned(vq_name, vq->vq_ring_size,
|
||||
- SOCKET_ID_ANY, RTE_MEMZONE_IOVA_CONTIG,
|
||||
+ numa_node, RTE_MEMZONE_IOVA_CONTIG,
|
||||
VIRTIO_PCI_VRING_ALIGN);
|
||||
if (mz == NULL) {
|
||||
if (rte_errno == EEXIST)
|
||||
@@ -418,7 +420,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
|
||||
snprintf(vq_hdr_name, sizeof(vq_hdr_name), "port%d_vq%d_hdr",
|
||||
dev->data->port_id, vtpci_queue_idx);
|
||||
hdr_mz = rte_memzone_reserve_aligned(vq_hdr_name, sz_hdr_mz,
|
||||
- SOCKET_ID_ANY, RTE_MEMZONE_IOVA_CONTIG,
|
||||
+ numa_node, RTE_MEMZONE_IOVA_CONTIG,
|
||||
RTE_CACHE_LINE_SIZE);
|
||||
if (hdr_mz == NULL) {
|
||||
if (rte_errno == EEXIST)
|
||||
@@ -435,7 +437,7 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
|
||||
sizeof(vq->sw_ring[0]);
|
||||
|
||||
sw_ring = rte_zmalloc_socket("sw_ring", sz_sw,
|
||||
- RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
|
||||
+ RTE_CACHE_LINE_SIZE, numa_node);
|
||||
if (!sw_ring) {
|
||||
PMD_INIT_LOG(ERR, "can not allocate RX soft ring");
|
||||
ret = -ENOMEM;
|
||||
--
|
||||
2.20.1
|
||||
|
@ -1,38 +0,0 @@
|
||||
From da9c7a3059fb4cffef8d1101a247fafabd9be7bd Mon Sep 17 00:00:00 2001
|
||||
From: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Date: Wed, 5 Dec 2018 14:11:57 -0800
|
||||
Subject: [PATCH 2/3] net/netvsc: enable SR-IOV
|
||||
|
||||
[ upstream commit 825ab257b5ce8235ab0cdc260e5b7b757e102875 ]
|
||||
|
||||
Make DPDK enable SRIOV flag in same way as Linux and FreeBSD.
|
||||
|
||||
Fixes: dc7680e8597c ("net/netvsc: support integrated VF")
|
||||
|
||||
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
(cherry picked from commit 21dc946c2b5524c7e6ec1fe4079864f3322dd483)
|
||||
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
---
|
||||
drivers/net/netvsc/hn_nvs.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/netvsc/hn_nvs.c b/drivers/net/netvsc/hn_nvs.c
|
||||
index 9690c5f8a..d58770e04 100644
|
||||
--- a/drivers/net/netvsc/hn_nvs.c
|
||||
+++ b/drivers/net/netvsc/hn_nvs.c
|
||||
@@ -326,9 +326,9 @@ hn_nvs_conf_ndis(struct hn_data *hv, unsigned int mtu)
|
||||
conf.mtu = mtu + ETHER_HDR_LEN;
|
||||
conf.caps = NVS_NDIS_CONF_VLAN;
|
||||
|
||||
- /* TODO enable SRIOV */
|
||||
- //if (hv->nvs_ver >= NVS_VERSION_5)
|
||||
- // conf.caps |= NVS_NDIS_CONF_SRIOV;
|
||||
+ /* enable SRIOV */
|
||||
+ if (hv->nvs_ver >= NVS_VERSION_5)
|
||||
+ conf.caps |= NVS_NDIS_CONF_SRIOV;
|
||||
|
||||
/* NOTE: No response. */
|
||||
error = hn_nvs_req_send(hv, &conf, sizeof(conf));
|
||||
--
|
||||
2.20.1
|
||||
|
141
SOURCES/0002-net-virtio-add-packed-virtqueue-helpers.patch
Normal file
141
SOURCES/0002-net-virtio-add-packed-virtqueue-helpers.patch
Normal file
@ -0,0 +1,141 @@
|
||||
From 652a2e3a1ba0db81ae1814e8c3cb989e9e89c4e0 Mon Sep 17 00:00:00 2001
|
||||
From: Jens Freimann <jfreimann@redhat.com>
|
||||
Date: Mon, 17 Dec 2018 22:31:31 +0100
|
||||
Subject: [PATCH 02/18] net/virtio: add packed virtqueue helpers
|
||||
|
||||
[ upstream commit e9f4feb7e6225f671b59375aff44b9d576121577 ]
|
||||
|
||||
Add helper functions to set/clear and check descriptor flags.
|
||||
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit e9f4feb7e6225f671b59375aff44b9d576121577)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_pci.h | 6 +++
|
||||
drivers/net/virtio/virtqueue.h | 72 ++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 76 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
|
||||
index 4c975a531..b22b62dad 100644
|
||||
--- a/drivers/net/virtio/virtio_pci.h
|
||||
+++ b/drivers/net/virtio/virtio_pci.h
|
||||
@@ -315,6 +315,12 @@ vtpci_with_feature(struct virtio_hw *hw, uint64_t bit)
|
||||
return (hw->guest_features & (1ULL << bit)) != 0;
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+vtpci_packed_queue(struct virtio_hw *hw)
|
||||
+{
|
||||
+ return vtpci_with_feature(hw, VIRTIO_F_RING_PACKED);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Function declaration from virtio_pci.c
|
||||
*/
|
||||
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
|
||||
index 1525c7d10..c32812427 100644
|
||||
--- a/drivers/net/virtio/virtqueue.h
|
||||
+++ b/drivers/net/virtio/virtqueue.h
|
||||
@@ -251,6 +251,31 @@ struct virtio_tx_region {
|
||||
__attribute__((__aligned__(16)));
|
||||
};
|
||||
|
||||
+static inline int
|
||||
+desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
|
||||
+{
|
||||
+ uint16_t used, avail, flags;
|
||||
+
|
||||
+ flags = desc->flags;
|
||||
+ used = !!(flags & VRING_DESC_F_USED(1));
|
||||
+ avail = !!(flags & VRING_DESC_F_AVAIL(1));
|
||||
+
|
||||
+ return avail == used && used == vq->used_wrap_counter;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static inline void
|
||||
+vring_desc_init_packed(struct virtqueue *vq, int n)
|
||||
+{
|
||||
+ int i;
|
||||
+ for (i = 0; i < n - 1; i++) {
|
||||
+ vq->ring_packed.desc_packed[i].id = i;
|
||||
+ vq->vq_descx[i].next = i + 1;
|
||||
+ }
|
||||
+ vq->ring_packed.desc_packed[i].id = i;
|
||||
+ vq->vq_descx[i].next = VQ_RING_DESC_CHAIN_END;
|
||||
+}
|
||||
+
|
||||
/* Chain all the descriptors in the ring with an END */
|
||||
static inline void
|
||||
vring_desc_init(struct vring_desc *dp, uint16_t n)
|
||||
@@ -262,13 +287,53 @@ vring_desc_init(struct vring_desc *dp, uint16_t n)
|
||||
dp[i].next = VQ_RING_DESC_CHAIN_END;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * Tell the backend not to interrupt us.
|
||||
+ */
|
||||
+static inline void
|
||||
+virtqueue_disable_intr_packed(struct virtqueue *vq)
|
||||
+{
|
||||
+ uint16_t *event_flags = &vq->ring_packed.driver_event->desc_event_flags;
|
||||
+
|
||||
+ *event_flags = RING_EVENT_FLAGS_DISABLE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/**
|
||||
* Tell the backend not to interrupt us.
|
||||
*/
|
||||
static inline void
|
||||
virtqueue_disable_intr(struct virtqueue *vq)
|
||||
{
|
||||
- vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
|
||||
+ if (vtpci_packed_queue(vq->hw))
|
||||
+ virtqueue_disable_intr_packed(vq);
|
||||
+ else
|
||||
+ vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Tell the backend to interrupt. Implementation for packed virtqueues.
|
||||
+ */
|
||||
+static inline void
|
||||
+virtqueue_enable_intr_packed(struct virtqueue *vq)
|
||||
+{
|
||||
+ uint16_t *event_flags = &vq->ring_packed.driver_event->desc_event_flags;
|
||||
+
|
||||
+
|
||||
+ if (vq->event_flags_shadow == RING_EVENT_FLAGS_DISABLE) {
|
||||
+ virtio_wmb();
|
||||
+ vq->event_flags_shadow = RING_EVENT_FLAGS_ENABLE;
|
||||
+ *event_flags = vq->event_flags_shadow;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Tell the backend to interrupt. Implementation for split virtqueues.
|
||||
+ */
|
||||
+static inline void
|
||||
+virtqueue_enable_intr_split(struct virtqueue *vq)
|
||||
+{
|
||||
+ vq->vq_ring.avail->flags &= (~VRING_AVAIL_F_NO_INTERRUPT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -277,7 +342,10 @@ virtqueue_disable_intr(struct virtqueue *vq)
|
||||
static inline void
|
||||
virtqueue_enable_intr(struct virtqueue *vq)
|
||||
{
|
||||
- vq->vq_ring.avail->flags &= (~VRING_AVAIL_F_NO_INTERRUPT);
|
||||
+ if (vtpci_packed_queue(vq->hw))
|
||||
+ virtqueue_enable_intr_packed(vq);
|
||||
+ else
|
||||
+ virtqueue_enable_intr_split(vq);
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
2.21.0
|
||||
|
@ -1,46 +0,0 @@
|
||||
From 0598625d2e17374b7d5693972f5acb59fef25f63 Mon Sep 17 00:00:00 2001
|
||||
From: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Date: Wed, 5 Dec 2018 14:11:58 -0800
|
||||
Subject: [PATCH 3/3] net/netvsc: disable multi-queue on older servers
|
||||
|
||||
[ upstream commit afbc22bf51ab98b9b61b11eb6d38278a9d577111 ]
|
||||
|
||||
NDIS multi-queue support is only in WS2012 or later. Check the NDIS
|
||||
version to limit to single queue on older versions. Similar code
|
||||
exists in Linux driver.
|
||||
|
||||
Fixes: 4e9c73e96e83 ("net/netvsc: add Hyper-V network device")
|
||||
|
||||
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
(cherry picked from commit d387b7ae45a520970ff55ea6ce75b48d5e69c4d9)
|
||||
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
---
|
||||
drivers/net/netvsc/hn_ethdev.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/netvsc/hn_ethdev.c b/drivers/net/netvsc/hn_ethdev.c
|
||||
index b330bf3d7..1256fa399 100644
|
||||
--- a/drivers/net/netvsc/hn_ethdev.c
|
||||
+++ b/drivers/net/netvsc/hn_ethdev.c
|
||||
@@ -732,6 +732,7 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev)
|
||||
hv->chim_res = &vmbus->resource[HV_SEND_BUF_MAP];
|
||||
hv->port_id = eth_dev->data->port_id;
|
||||
hv->latency = HN_CHAN_LATENCY_NS;
|
||||
+ hv->max_queues = 1;
|
||||
|
||||
err = hn_parse_args(eth_dev);
|
||||
if (err)
|
||||
@@ -770,6 +771,10 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev)
|
||||
if (err)
|
||||
goto failed;
|
||||
|
||||
+ /* Multi queue requires later versions of windows server */
|
||||
+ if (hv->nvs_ver < NVS_VERSION_5)
|
||||
+ return 0;
|
||||
+
|
||||
max_chan = rte_vmbus_max_channels(vmbus);
|
||||
PMD_INIT_LOG(DEBUG, "VMBus max channels %d", max_chan);
|
||||
if (max_chan <= 0)
|
||||
--
|
||||
2.20.1
|
||||
|
175
SOURCES/0003-net-virtio-vring-init-for-packed-queues.patch
Normal file
175
SOURCES/0003-net-virtio-vring-init-for-packed-queues.patch
Normal file
@ -0,0 +1,175 @@
|
||||
From 4e832cad1879f87a694e2f78b8718f986f7c76e2 Mon Sep 17 00:00:00 2001
|
||||
From: Jens Freimann <jfreimann@redhat.com>
|
||||
Date: Mon, 17 Dec 2018 22:31:32 +0100
|
||||
Subject: [PATCH 03/18] net/virtio: vring init for packed queues
|
||||
|
||||
[ upstream commit f803734b0f2e6c556d9bf7fe8f11638429e3a00f ]
|
||||
|
||||
Add and initialize descriptor data structures.
|
||||
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit f803734b0f2e6c556d9bf7fe8f11638429e3a00f)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_ethdev.c | 32 ++++++++++++++++++++----------
|
||||
drivers/net/virtio/virtio_ring.h | 28 ++++++++++++++++++++++----
|
||||
drivers/net/virtio/virtqueue.h | 2 +-
|
||||
3 files changed, 46 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
|
||||
index 2ba66d291..ee52e3cdb 100644
|
||||
--- a/drivers/net/virtio/virtio_ethdev.c
|
||||
+++ b/drivers/net/virtio/virtio_ethdev.c
|
||||
@@ -299,20 +299,22 @@ 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);
|
||||
vq->vq_free_cnt = vq->vq_nentries;
|
||||
memset(vq->vq_descx, 0, sizeof(struct vq_desc_extra) * vq->vq_nentries);
|
||||
-
|
||||
- vring_desc_init(vr->desc, size);
|
||||
-
|
||||
+ if (vtpci_packed_queue(vq->hw)) {
|
||||
+ vring_init_packed(&vq->ring_packed, ring_mem,
|
||||
+ VIRTIO_PCI_VRING_ALIGN, size);
|
||||
+ vring_desc_init_packed(vq, size);
|
||||
+ } else {
|
||||
+ vring_init_split(vr, ring_mem, VIRTIO_PCI_VRING_ALIGN, size);
|
||||
+ vring_desc_init_split(vr->desc, size);
|
||||
+ }
|
||||
/*
|
||||
* Disable device(host) interrupting guest
|
||||
*/
|
||||
@@ -382,11 +384,16 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
|
||||
vq->hw = hw;
|
||||
vq->vq_queue_index = vtpci_queue_idx;
|
||||
vq->vq_nentries = vq_size;
|
||||
+ vq->event_flags_shadow = 0;
|
||||
+ if (vtpci_packed_queue(hw)) {
|
||||
+ vq->avail_wrap_counter = 1;
|
||||
+ vq->used_wrap_counter = 1;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* 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);
|
||||
@@ -489,7 +496,8 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
|
||||
for (i = 0; i < vq_size; i++) {
|
||||
struct vring_desc *start_dp = txr[i].tx_indir;
|
||||
|
||||
- vring_desc_init(start_dp, RTE_DIM(txr[i].tx_indir));
|
||||
+ vring_desc_init_split(start_dp,
|
||||
+ RTE_DIM(txr[i].tx_indir));
|
||||
|
||||
/* first indirect descriptor is always the tx header */
|
||||
start_dp->addr = txvq->virtio_net_hdr_mem
|
||||
@@ -1486,7 +1494,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_RING_PACKED))
|
||||
hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);
|
||||
else
|
||||
hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr);
|
||||
@@ -1906,7 +1915,8 @@ virtio_dev_configure(struct rte_eth_dev *dev)
|
||||
|
||||
if (vtpci_with_feature(hw, VIRTIO_F_IN_ORDER)) {
|
||||
hw->use_inorder_tx = 1;
|
||||
- if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
|
||||
+ if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF) &&
|
||||
+ !vtpci_packed_queue(hw)) {
|
||||
hw->use_inorder_rx = 1;
|
||||
hw->use_simple_rx = 0;
|
||||
} else {
|
||||
diff --git a/drivers/net/virtio/virtio_ring.h b/drivers/net/virtio/virtio_ring.h
|
||||
index 464449074..1760823c6 100644
|
||||
--- a/drivers/net/virtio/virtio_ring.h
|
||||
+++ b/drivers/net/virtio/virtio_ring.h
|
||||
@@ -125,10 +125,18 @@ 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_packed_queue(hw)) {
|
||||
+ size = num * sizeof(struct vring_packed_desc);
|
||||
+ size += sizeof(struct vring_packed_desc_event);
|
||||
+ size = RTE_ALIGN_CEIL(size, align);
|
||||
+ size += sizeof(struct vring_packed_desc_event);
|
||||
+ return size;
|
||||
+ }
|
||||
+
|
||||
size = num * sizeof(struct vring_desc);
|
||||
size += sizeof(struct vring_avail) + (num * sizeof(uint16_t));
|
||||
size = RTE_ALIGN_CEIL(size, align);
|
||||
@@ -136,10 +144,9 @@ vring_size(unsigned int num, unsigned long align)
|
||||
(num * sizeof(struct vring_used_elem));
|
||||
return size;
|
||||
}
|
||||
-
|
||||
static inline void
|
||||
-vring_init(struct vring *vr, unsigned int num, uint8_t *p,
|
||||
- unsigned long align)
|
||||
+vring_init_split(struct vring *vr, uint8_t *p, unsigned long align,
|
||||
+ unsigned int num)
|
||||
{
|
||||
vr->num = num;
|
||||
vr->desc = (struct vring_desc *) p;
|
||||
@@ -149,6 +156,19 @@ vring_init(struct vring *vr, unsigned int num, uint8_t *p,
|
||||
RTE_ALIGN_CEIL((uintptr_t)(&vr->avail->ring[num]), align);
|
||||
}
|
||||
|
||||
+static inline void
|
||||
+vring_init_packed(struct vring_packed *vr, uint8_t *p, unsigned long align,
|
||||
+ unsigned int num)
|
||||
+{
|
||||
+ vr->num = num;
|
||||
+ vr->desc_packed = (struct vring_packed_desc *)p;
|
||||
+ vr->driver_event = (struct vring_packed_desc_event *)(p +
|
||||
+ vr->num * sizeof(struct vring_packed_desc));
|
||||
+ vr->device_event = (struct vring_packed_desc_event *)
|
||||
+ RTE_ALIGN_CEIL((uintptr_t)(vr->driver_event +
|
||||
+ sizeof(struct vring_packed_desc_event)), align);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* The following is used with VIRTIO_RING_F_EVENT_IDX.
|
||||
* Assuming a given event_idx value from the other size, if we have
|
||||
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
|
||||
index c32812427..d08ef9112 100644
|
||||
--- a/drivers/net/virtio/virtqueue.h
|
||||
+++ b/drivers/net/virtio/virtqueue.h
|
||||
@@ -278,7 +278,7 @@ vring_desc_init_packed(struct virtqueue *vq, int n)
|
||||
|
||||
/* Chain all the descriptors in the ring with an END */
|
||||
static inline void
|
||||
-vring_desc_init(struct vring_desc *dp, uint16_t n)
|
||||
+vring_desc_init_split(struct vring_desc *dp, uint16_t n)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
--
|
||||
2.21.0
|
||||
|
41
SOURCES/0004-net-virtio-dump-packed-virtqueue-data.patch
Normal file
41
SOURCES/0004-net-virtio-dump-packed-virtqueue-data.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From 2dc70f1db67091cc3a9131d2093da464738b31d8 Mon Sep 17 00:00:00 2001
|
||||
From: Jens Freimann <jfreimann@redhat.com>
|
||||
Date: Mon, 17 Dec 2018 22:31:33 +0100
|
||||
Subject: [PATCH 04/18] net/virtio: dump packed virtqueue data
|
||||
|
||||
[ upstream commit 56785a2d6fad987c025278909307db776df59bd9 ]
|
||||
|
||||
Add support to dump packed virtqueue data to the
|
||||
VIRTQUEUE_DUMP() macro.
|
||||
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit 56785a2d6fad987c025278909307db776df59bd9)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtqueue.h | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
|
||||
index d08ef9112..e9c35a553 100644
|
||||
--- a/drivers/net/virtio/virtqueue.h
|
||||
+++ b/drivers/net/virtio/virtqueue.h
|
||||
@@ -434,6 +434,15 @@ virtqueue_notify(struct virtqueue *vq)
|
||||
uint16_t used_idx, nused; \
|
||||
used_idx = (vq)->vq_ring.used->idx; \
|
||||
nused = (uint16_t)(used_idx - (vq)->vq_used_cons_idx); \
|
||||
+ if (vtpci_packed_queue((vq)->hw)) { \
|
||||
+ PMD_INIT_LOG(DEBUG, \
|
||||
+ "VQ: - size=%d; free=%d; used_cons_idx=%d; avail_idx=%d;" \
|
||||
+ "VQ: - avail_wrap_counter=%d; used_wrap_counter=%d", \
|
||||
+ (vq)->vq_nentries, (vq)->vq_free_cnt, (vq)->vq_used_cons_idx, \
|
||||
+ (vq)->vq_avail_idx, (vq)->avail_wrap_counter, \
|
||||
+ (vq)->used_wrap_counter); \
|
||||
+ break; \
|
||||
+ } \
|
||||
PMD_INIT_LOG(DEBUG, \
|
||||
"VQ: - size=%d; free=%d; used=%d; desc_head_idx=%d;" \
|
||||
" avail.idx=%d; used_cons_idx=%d; used.idx=%d;" \
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,448 @@
|
||||
From 97ee69c836bfb08e674fd0f28d1fc7a14f2d4de0 Mon Sep 17 00:00:00 2001
|
||||
From: Jens Freimann <jfreimann@redhat.com>
|
||||
Date: Mon, 17 Dec 2018 22:31:34 +0100
|
||||
Subject: [PATCH 05/18] net/virtio: implement Tx path for packed queues
|
||||
|
||||
[ upstream commit 892dc798fa9c24e6172b8bcecc9586f2f9a7a49e ]
|
||||
|
||||
This implements the transmit path for devices with
|
||||
support for packed virtqueues.
|
||||
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit 892dc798fa9c24e6172b8bcecc9586f2f9a7a49e)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_ethdev.c | 56 ++++---
|
||||
drivers/net/virtio/virtio_ethdev.h | 2 +
|
||||
drivers/net/virtio/virtio_rxtx.c | 236 ++++++++++++++++++++++++++++-
|
||||
drivers/net/virtio/virtqueue.h | 20 ++-
|
||||
4 files changed, 292 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
|
||||
index ee52e3cdb..6023d6f2c 100644
|
||||
--- a/drivers/net/virtio/virtio_ethdev.c
|
||||
+++ b/drivers/net/virtio/virtio_ethdev.c
|
||||
@@ -388,6 +388,9 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
|
||||
if (vtpci_packed_queue(hw)) {
|
||||
vq->avail_wrap_counter = 1;
|
||||
vq->used_wrap_counter = 1;
|
||||
+ vq->avail_used_flags =
|
||||
+ VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
|
||||
+ VRING_DESC_F_USED(!vq->avail_wrap_counter);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -495,17 +498,26 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
|
||||
memset(txr, 0, vq_size * sizeof(*txr));
|
||||
for (i = 0; i < vq_size; i++) {
|
||||
struct vring_desc *start_dp = txr[i].tx_indir;
|
||||
-
|
||||
- vring_desc_init_split(start_dp,
|
||||
- RTE_DIM(txr[i].tx_indir));
|
||||
+ struct vring_packed_desc *start_dp_packed =
|
||||
+ txr[i].tx_indir_pq;
|
||||
|
||||
/* first indirect descriptor is always the tx header */
|
||||
- start_dp->addr = txvq->virtio_net_hdr_mem
|
||||
- + i * sizeof(*txr)
|
||||
- + offsetof(struct virtio_tx_region, tx_hdr);
|
||||
-
|
||||
- start_dp->len = hw->vtnet_hdr_size;
|
||||
- start_dp->flags = VRING_DESC_F_NEXT;
|
||||
+ if (vtpci_packed_queue(hw)) {
|
||||
+ start_dp_packed->addr = txvq->virtio_net_hdr_mem
|
||||
+ + i * sizeof(*txr)
|
||||
+ + offsetof(struct virtio_tx_region,
|
||||
+ tx_hdr);
|
||||
+ start_dp_packed->len = hw->vtnet_hdr_size;
|
||||
+ } else {
|
||||
+ vring_desc_init_split(start_dp,
|
||||
+ RTE_DIM(txr[i].tx_indir));
|
||||
+ start_dp->addr = txvq->virtio_net_hdr_mem
|
||||
+ + i * sizeof(*txr)
|
||||
+ + offsetof(struct virtio_tx_region,
|
||||
+ tx_hdr);
|
||||
+ start_dp->len = hw->vtnet_hdr_size;
|
||||
+ start_dp->flags = VRING_DESC_F_NEXT;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1334,6 +1346,23 @@ set_rxtx_funcs(struct rte_eth_dev *eth_dev)
|
||||
{
|
||||
struct virtio_hw *hw = eth_dev->data->dev_private;
|
||||
|
||||
+ if (vtpci_packed_queue(hw)) {
|
||||
+ PMD_INIT_LOG(INFO,
|
||||
+ "virtio: using packed ring standard Tx path on port %u",
|
||||
+ eth_dev->data->port_id);
|
||||
+ eth_dev->tx_pkt_burst = virtio_xmit_pkts_packed;
|
||||
+ } else {
|
||||
+ if (hw->use_inorder_tx) {
|
||||
+ PMD_INIT_LOG(INFO, "virtio: using inorder Tx path on port %u",
|
||||
+ eth_dev->data->port_id);
|
||||
+ eth_dev->tx_pkt_burst = virtio_xmit_pkts_inorder;
|
||||
+ } else {
|
||||
+ PMD_INIT_LOG(INFO, "virtio: using standard Tx path on port %u",
|
||||
+ eth_dev->data->port_id);
|
||||
+ eth_dev->tx_pkt_burst = virtio_xmit_pkts;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (hw->use_simple_rx) {
|
||||
PMD_INIT_LOG(INFO, "virtio: using simple Rx path on port %u",
|
||||
eth_dev->data->port_id);
|
||||
@@ -1354,15 +1383,6 @@ set_rxtx_funcs(struct rte_eth_dev *eth_dev)
|
||||
eth_dev->rx_pkt_burst = &virtio_recv_pkts;
|
||||
}
|
||||
|
||||
- if (hw->use_inorder_tx) {
|
||||
- PMD_INIT_LOG(INFO, "virtio: using inorder Tx path on port %u",
|
||||
- eth_dev->data->port_id);
|
||||
- eth_dev->tx_pkt_burst = virtio_xmit_pkts_inorder;
|
||||
- } else {
|
||||
- PMD_INIT_LOG(INFO, "virtio: using standard Tx path on port %u",
|
||||
- eth_dev->data->port_id);
|
||||
- eth_dev->tx_pkt_burst = virtio_xmit_pkts;
|
||||
- }
|
||||
}
|
||||
|
||||
/* Only support 1:1 queue/interrupt mapping so far.
|
||||
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
|
||||
index e0f80e5a4..05d355180 100644
|
||||
--- a/drivers/net/virtio/virtio_ethdev.h
|
||||
+++ b/drivers/net/virtio/virtio_ethdev.h
|
||||
@@ -82,6 +82,8 @@ uint16_t virtio_recv_mergeable_pkts_inorder(void *rx_queue,
|
||||
|
||||
uint16_t virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
|
||||
uint16_t nb_pkts);
|
||||
+uint16_t virtio_xmit_pkts_packed(void *tx_queue, struct rte_mbuf **tx_pkts,
|
||||
+ uint16_t nb_pkts);
|
||||
|
||||
uint16_t virtio_xmit_pkts_inorder(void *tx_queue, struct rte_mbuf **tx_pkts,
|
||||
uint16_t nb_pkts);
|
||||
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
|
||||
index eb891433e..ab74917a8 100644
|
||||
--- a/drivers/net/virtio/virtio_rxtx.c
|
||||
+++ b/drivers/net/virtio/virtio_rxtx.c
|
||||
@@ -88,6 +88,23 @@ vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
|
||||
dp->next = VQ_RING_DESC_CHAIN_END;
|
||||
}
|
||||
|
||||
+static void
|
||||
+vq_ring_free_id_packed(struct virtqueue *vq, uint16_t id)
|
||||
+{
|
||||
+ struct vq_desc_extra *dxp;
|
||||
+
|
||||
+ dxp = &vq->vq_descx[id];
|
||||
+ vq->vq_free_cnt += dxp->ndescs;
|
||||
+
|
||||
+ if (vq->vq_desc_tail_idx == VQ_RING_DESC_CHAIN_END)
|
||||
+ vq->vq_desc_head_idx = id;
|
||||
+ else
|
||||
+ vq->vq_descx[vq->vq_desc_tail_idx].next = id;
|
||||
+
|
||||
+ vq->vq_desc_tail_idx = id;
|
||||
+ dxp->next = VQ_RING_DESC_CHAIN_END;
|
||||
+}
|
||||
+
|
||||
static uint16_t
|
||||
virtqueue_dequeue_burst_rx(struct virtqueue *vq, struct rte_mbuf **rx_pkts,
|
||||
uint32_t *len, uint16_t num)
|
||||
@@ -165,6 +182,33 @@ virtqueue_dequeue_rx_inorder(struct virtqueue *vq,
|
||||
#endif
|
||||
|
||||
/* Cleanup from completed transmits. */
|
||||
+static void
|
||||
+virtio_xmit_cleanup_packed(struct virtqueue *vq, int num)
|
||||
+{
|
||||
+ uint16_t used_idx, id;
|
||||
+ uint16_t size = vq->vq_nentries;
|
||||
+ struct vring_packed_desc *desc = vq->ring_packed.desc_packed;
|
||||
+ struct vq_desc_extra *dxp;
|
||||
+
|
||||
+ used_idx = vq->vq_used_cons_idx;
|
||||
+ while (num-- && desc_is_used(&desc[used_idx], vq)) {
|
||||
+ used_idx = vq->vq_used_cons_idx;
|
||||
+ id = desc[used_idx].id;
|
||||
+ dxp = &vq->vq_descx[id];
|
||||
+ vq->vq_used_cons_idx += dxp->ndescs;
|
||||
+ if (vq->vq_used_cons_idx >= size) {
|
||||
+ vq->vq_used_cons_idx -= size;
|
||||
+ vq->used_wrap_counter ^= 1;
|
||||
+ }
|
||||
+ vq_ring_free_id_packed(vq, id);
|
||||
+ if (dxp->cookie != NULL) {
|
||||
+ rte_pktmbuf_free(dxp->cookie);
|
||||
+ dxp->cookie = NULL;
|
||||
+ }
|
||||
+ used_idx = vq->vq_used_cons_idx;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
virtio_xmit_cleanup(struct virtqueue *vq, uint16_t num)
|
||||
{
|
||||
@@ -456,6 +500,107 @@ virtqueue_enqueue_xmit_inorder(struct virtnet_tx *txvq,
|
||||
vq->vq_desc_head_idx = idx & (vq->vq_nentries - 1);
|
||||
}
|
||||
|
||||
+static inline void
|
||||
+virtqueue_enqueue_xmit_packed(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
|
||||
+ uint16_t needed, int can_push)
|
||||
+{
|
||||
+ struct virtio_tx_region *txr = txvq->virtio_net_hdr_mz->addr;
|
||||
+ struct vq_desc_extra *dxp;
|
||||
+ struct virtqueue *vq = txvq->vq;
|
||||
+ struct vring_packed_desc *start_dp, *head_dp;
|
||||
+ uint16_t idx, id, head_idx, head_flags;
|
||||
+ uint16_t head_size = vq->hw->vtnet_hdr_size;
|
||||
+ struct virtio_net_hdr *hdr;
|
||||
+ uint16_t prev;
|
||||
+
|
||||
+ id = vq->vq_desc_head_idx;
|
||||
+
|
||||
+ dxp = &vq->vq_descx[id];
|
||||
+ dxp->ndescs = needed;
|
||||
+ dxp->cookie = cookie;
|
||||
+
|
||||
+ head_idx = vq->vq_avail_idx;
|
||||
+ idx = head_idx;
|
||||
+ prev = head_idx;
|
||||
+ start_dp = vq->ring_packed.desc_packed;
|
||||
+
|
||||
+ head_dp = &vq->ring_packed.desc_packed[idx];
|
||||
+ head_flags = cookie->next ? VRING_DESC_F_NEXT : 0;
|
||||
+ head_flags |= vq->avail_used_flags;
|
||||
+
|
||||
+ if (can_push) {
|
||||
+ /* prepend cannot fail, checked by caller */
|
||||
+ hdr = (struct virtio_net_hdr *)
|
||||
+ rte_pktmbuf_prepend(cookie, head_size);
|
||||
+ /* rte_pktmbuf_prepend() counts the hdr size to the pkt length,
|
||||
+ * which is wrong. Below subtract restores correct pkt size.
|
||||
+ */
|
||||
+ cookie->pkt_len -= head_size;
|
||||
+
|
||||
+ /* if offload disabled, it is not zeroed below, do it now */
|
||||
+ if (!vq->hw->has_tx_offload) {
|
||||
+ 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 {
|
||||
+ /* 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;
|
||||
+ hdr = (struct virtio_net_hdr *)&txr[idx].tx_hdr;
|
||||
+ idx++;
|
||||
+ if (idx >= vq->vq_nentries) {
|
||||
+ idx -= vq->vq_nentries;
|
||||
+ vq->avail_wrap_counter ^= 1;
|
||||
+ vq->avail_used_flags =
|
||||
+ VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
|
||||
+ VRING_DESC_F_USED(!vq->avail_wrap_counter);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ virtqueue_xmit_offload(hdr, cookie, vq->hw->has_tx_offload);
|
||||
+
|
||||
+ do {
|
||||
+ uint16_t flags;
|
||||
+
|
||||
+ start_dp[idx].addr = VIRTIO_MBUF_DATA_DMA_ADDR(cookie, vq);
|
||||
+ start_dp[idx].len = cookie->data_len;
|
||||
+ if (likely(idx != head_idx)) {
|
||||
+ flags = cookie->next ? VRING_DESC_F_NEXT : 0;
|
||||
+ flags |= vq->avail_used_flags;
|
||||
+ start_dp[idx].flags = flags;
|
||||
+ }
|
||||
+ prev = idx;
|
||||
+ idx++;
|
||||
+ if (idx >= vq->vq_nentries) {
|
||||
+ idx -= vq->vq_nentries;
|
||||
+ vq->avail_wrap_counter ^= 1;
|
||||
+ vq->avail_used_flags =
|
||||
+ VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
|
||||
+ VRING_DESC_F_USED(!vq->avail_wrap_counter);
|
||||
+ }
|
||||
+ } while ((cookie = cookie->next) != NULL);
|
||||
+
|
||||
+ start_dp[prev].id = id;
|
||||
+
|
||||
+ vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt - needed);
|
||||
+
|
||||
+ vq->vq_desc_head_idx = dxp->next;
|
||||
+ if (vq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END)
|
||||
+ vq->vq_desc_tail_idx = VQ_RING_DESC_CHAIN_END;
|
||||
+
|
||||
+ vq->vq_avail_idx = idx;
|
||||
+
|
||||
+ rte_smp_wmb();
|
||||
+ head_dp->flags = head_flags;
|
||||
+}
|
||||
+
|
||||
static inline void
|
||||
virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
|
||||
uint16_t needed, int use_indirect, int can_push,
|
||||
@@ -733,8 +878,10 @@ virtio_dev_tx_queue_setup_finish(struct rte_eth_dev *dev,
|
||||
|
||||
PMD_INIT_FUNC_TRACE();
|
||||
|
||||
- if (hw->use_inorder_tx)
|
||||
- vq->vq_ring.desc[vq->vq_nentries - 1].next = 0;
|
||||
+ if (!vtpci_packed_queue(hw)) {
|
||||
+ if (hw->use_inorder_tx)
|
||||
+ vq->vq_ring.desc[vq->vq_nentries - 1].next = 0;
|
||||
+ }
|
||||
|
||||
VIRTQUEUE_DUMP(vq);
|
||||
|
||||
@@ -1346,6 +1493,91 @@ virtio_recv_mergeable_pkts(void *rx_queue,
|
||||
return nb_rx;
|
||||
}
|
||||
|
||||
+uint16_t
|
||||
+virtio_xmit_pkts_packed(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_tx = 0;
|
||||
+ int error;
|
||||
+
|
||||
+ if (unlikely(hw->started == 0 && tx_pkts != hw->inject_pkts))
|
||||
+ return nb_tx;
|
||||
+
|
||||
+ if (unlikely(nb_pkts < 1))
|
||||
+ return nb_pkts;
|
||||
+
|
||||
+ PMD_TX_LOG(DEBUG, "%d packets to xmit", nb_pkts);
|
||||
+
|
||||
+ if (nb_pkts > vq->vq_free_cnt)
|
||||
+ virtio_xmit_cleanup_packed(vq, nb_pkts - vq->vq_free_cnt);
|
||||
+
|
||||
+ for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
|
||||
+ struct rte_mbuf *txm = tx_pkts[nb_tx];
|
||||
+ int can_push = 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;
|
||||
+
|
||||
+ /* How many main ring entries are needed to this Tx?
|
||||
+ * any_layout => number of segments
|
||||
+ * default => number of segments + 1
|
||||
+ */
|
||||
+ slots = txm->nb_segs + !can_push;
|
||||
+ need = slots - vq->vq_free_cnt;
|
||||
+
|
||||
+ /* Positive value indicates it need free vring descriptors */
|
||||
+ if (unlikely(need > 0)) {
|
||||
+ virtio_rmb();
|
||||
+ need = RTE_MIN(need, (int)nb_pkts);
|
||||
+ virtio_xmit_cleanup_packed(vq, need);
|
||||
+ need = slots - vq->vq_free_cnt;
|
||||
+ if (unlikely(need > 0)) {
|
||||
+ PMD_TX_LOG(ERR,
|
||||
+ "No free tx descriptors to transmit");
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Enqueue Packet buffers */
|
||||
+ virtqueue_enqueue_xmit_packed(txvq, txm, slots, can_push);
|
||||
+
|
||||
+ txvq->stats.bytes += txm->pkt_len;
|
||||
+ virtio_update_packet_stats(&txvq->stats, txm);
|
||||
+ }
|
||||
+
|
||||
+ txvq->stats.packets += nb_tx;
|
||||
+
|
||||
+ if (likely(nb_tx)) {
|
||||
+ if (unlikely(virtqueue_kick_prepare_packed(vq))) {
|
||||
+ virtqueue_notify(vq);
|
||||
+ PMD_TX_LOG(DEBUG, "Notified backend after xmit");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return nb_tx;
|
||||
+}
|
||||
+
|
||||
uint16_t
|
||||
virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
|
||||
{
|
||||
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
|
||||
index e9c35a553..b142fd488 100644
|
||||
--- a/drivers/net/virtio/virtqueue.h
|
||||
+++ b/drivers/net/virtio/virtqueue.h
|
||||
@@ -247,8 +247,12 @@ struct virtio_net_hdr_mrg_rxbuf {
|
||||
#define VIRTIO_MAX_TX_INDIRECT 8
|
||||
struct virtio_tx_region {
|
||||
struct virtio_net_hdr_mrg_rxbuf tx_hdr;
|
||||
- struct vring_desc tx_indir[VIRTIO_MAX_TX_INDIRECT]
|
||||
- __attribute__((__aligned__(16)));
|
||||
+ union {
|
||||
+ struct vring_desc tx_indir[VIRTIO_MAX_TX_INDIRECT]
|
||||
+ __attribute__((__aligned__(16)));
|
||||
+ struct vring_packed_desc tx_indir_pq[VIRTIO_MAX_TX_INDIRECT]
|
||||
+ __attribute__((__aligned__(16)));
|
||||
+ };
|
||||
};
|
||||
|
||||
static inline int
|
||||
@@ -380,6 +384,7 @@ virtio_get_queue_type(struct virtio_hw *hw, uint16_t vtpci_queue_idx)
|
||||
#define VIRTQUEUE_NUSED(vq) ((uint16_t)((vq)->vq_ring.used->idx - (vq)->vq_used_cons_idx))
|
||||
|
||||
void vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx);
|
||||
+void vq_ring_free_chain_packed(struct virtqueue *vq, uint16_t used_idx);
|
||||
void vq_ring_free_inorder(struct virtqueue *vq, uint16_t desc_idx,
|
||||
uint16_t num);
|
||||
|
||||
@@ -418,6 +423,17 @@ virtqueue_kick_prepare(struct virtqueue *vq)
|
||||
return !(vq->vq_ring.used->flags & VRING_USED_F_NO_NOTIFY);
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+virtqueue_kick_prepare_packed(struct virtqueue *vq)
|
||||
+{
|
||||
+ uint16_t flags;
|
||||
+
|
||||
+ virtio_mb();
|
||||
+ flags = vq->ring_packed.device_event->desc_event_flags;
|
||||
+
|
||||
+ return flags != RING_EVENT_FLAGS_DISABLE;
|
||||
+}
|
||||
+
|
||||
static inline void
|
||||
virtqueue_notify(struct virtqueue *vq)
|
||||
{
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,613 @@
|
||||
From a1168f29a051eba2344407d72267b5d5f648d80c Mon Sep 17 00:00:00 2001
|
||||
From: Jens Freimann <jfreimann@redhat.com>
|
||||
Date: Mon, 17 Dec 2018 22:31:35 +0100
|
||||
Subject: [PATCH 06/18] net/virtio: implement Rx path for packed queues
|
||||
|
||||
[ upstream commit a76290c8f1cf9c4774c23592921302a04a90bded ]
|
||||
|
||||
Implement the receive part.
|
||||
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit a76290c8f1cf9c4774c23592921302a04a90bded)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_ethdev.c | 56 +++--
|
||||
drivers/net/virtio/virtio_ethdev.h | 5 +
|
||||
drivers/net/virtio/virtio_rxtx.c | 375 ++++++++++++++++++++++++++++-
|
||||
drivers/net/virtio/virtqueue.c | 43 +++-
|
||||
4 files changed, 457 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
|
||||
index 6023d6f2c..4ef1da393 100644
|
||||
--- a/drivers/net/virtio/virtio_ethdev.c
|
||||
+++ b/drivers/net/virtio/virtio_ethdev.c
|
||||
@@ -1363,24 +1363,40 @@ set_rxtx_funcs(struct rte_eth_dev *eth_dev)
|
||||
}
|
||||
}
|
||||
|
||||
- if (hw->use_simple_rx) {
|
||||
- PMD_INIT_LOG(INFO, "virtio: using simple Rx path on port %u",
|
||||
- eth_dev->data->port_id);
|
||||
- eth_dev->rx_pkt_burst = virtio_recv_pkts_vec;
|
||||
- } else if (hw->use_inorder_rx) {
|
||||
- PMD_INIT_LOG(INFO,
|
||||
- "virtio: using inorder mergeable buffer Rx path on port %u",
|
||||
- eth_dev->data->port_id);
|
||||
- eth_dev->rx_pkt_burst = &virtio_recv_mergeable_pkts_inorder;
|
||||
- } else if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
|
||||
- PMD_INIT_LOG(INFO,
|
||||
- "virtio: using mergeable buffer Rx path on port %u",
|
||||
- eth_dev->data->port_id);
|
||||
- eth_dev->rx_pkt_burst = &virtio_recv_mergeable_pkts;
|
||||
+ if (vtpci_packed_queue(hw)) {
|
||||
+ if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
|
||||
+ PMD_INIT_LOG(INFO,
|
||||
+ "virtio: using packed ring mergeable buffer Rx path on port %u",
|
||||
+ eth_dev->data->port_id);
|
||||
+ eth_dev->rx_pkt_burst =
|
||||
+ &virtio_recv_mergeable_pkts_packed;
|
||||
+ } else {
|
||||
+ PMD_INIT_LOG(INFO,
|
||||
+ "virtio: using packed ring standard Rx path on port %u",
|
||||
+ eth_dev->data->port_id);
|
||||
+ eth_dev->rx_pkt_burst = &virtio_recv_pkts_packed;
|
||||
+ }
|
||||
} else {
|
||||
- PMD_INIT_LOG(INFO, "virtio: using standard Rx path on port %u",
|
||||
- eth_dev->data->port_id);
|
||||
- eth_dev->rx_pkt_burst = &virtio_recv_pkts;
|
||||
+ if (hw->use_simple_rx) {
|
||||
+ PMD_INIT_LOG(INFO, "virtio: using simple Rx path on port %u",
|
||||
+ eth_dev->data->port_id);
|
||||
+ eth_dev->rx_pkt_burst = virtio_recv_pkts_vec;
|
||||
+ } else if (hw->use_inorder_rx) {
|
||||
+ PMD_INIT_LOG(INFO,
|
||||
+ "virtio: using inorder mergeable buffer Rx path on port %u",
|
||||
+ eth_dev->data->port_id);
|
||||
+ eth_dev->rx_pkt_burst =
|
||||
+ &virtio_recv_mergeable_pkts_inorder;
|
||||
+ } else if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
|
||||
+ PMD_INIT_LOG(INFO,
|
||||
+ "virtio: using mergeable buffer Rx path on port %u",
|
||||
+ eth_dev->data->port_id);
|
||||
+ eth_dev->rx_pkt_burst = &virtio_recv_mergeable_pkts;
|
||||
+ } else {
|
||||
+ PMD_INIT_LOG(INFO, "virtio: using standard Rx path on port %u",
|
||||
+ eth_dev->data->port_id);
|
||||
+ eth_dev->rx_pkt_burst = &virtio_recv_pkts;
|
||||
+ }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1944,6 +1960,12 @@ virtio_dev_configure(struct rte_eth_dev *dev)
|
||||
}
|
||||
}
|
||||
|
||||
+ if (vtpci_packed_queue(hw)) {
|
||||
+ hw->use_simple_rx = 0;
|
||||
+ hw->use_inorder_rx = 0;
|
||||
+ hw->use_inorder_tx = 0;
|
||||
+ }
|
||||
+
|
||||
#if defined RTE_ARCH_ARM64 || defined RTE_ARCH_ARM
|
||||
if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON)) {
|
||||
hw->use_simple_rx = 0;
|
||||
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
|
||||
index 05d355180..88b8c42a3 100644
|
||||
--- a/drivers/net/virtio/virtio_ethdev.h
|
||||
+++ b/drivers/net/virtio/virtio_ethdev.h
|
||||
@@ -73,10 +73,15 @@ int virtio_dev_tx_queue_setup_finish(struct rte_eth_dev *dev,
|
||||
|
||||
uint16_t virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
|
||||
uint16_t nb_pkts);
|
||||
+uint16_t virtio_recv_pkts_packed(void *rx_queue, struct rte_mbuf **rx_pkts,
|
||||
+ uint16_t nb_pkts);
|
||||
|
||||
uint16_t virtio_recv_mergeable_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
|
||||
uint16_t nb_pkts);
|
||||
|
||||
+uint16_t virtio_recv_mergeable_pkts_packed(void *rx_queue,
|
||||
+ struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
|
||||
+
|
||||
uint16_t virtio_recv_mergeable_pkts_inorder(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 ab74917a8..0bcf3b08a 100644
|
||||
--- a/drivers/net/virtio/virtio_rxtx.c
|
||||
+++ b/drivers/net/virtio/virtio_rxtx.c
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "virtqueue.h"
|
||||
#include "virtio_rxtx.h"
|
||||
#include "virtio_rxtx_simple.h"
|
||||
+#include "virtio_ring.h"
|
||||
|
||||
#ifdef RTE_LIBRTE_VIRTIO_DEBUG_DUMP
|
||||
#define VIRTIO_DUMP_PACKET(m, len) rte_pktmbuf_dump(stdout, m, len)
|
||||
@@ -105,6 +106,47 @@ vq_ring_free_id_packed(struct virtqueue *vq, uint16_t id)
|
||||
dxp->next = VQ_RING_DESC_CHAIN_END;
|
||||
}
|
||||
|
||||
+static uint16_t
|
||||
+virtqueue_dequeue_burst_rx_packed(struct virtqueue *vq,
|
||||
+ struct rte_mbuf **rx_pkts,
|
||||
+ uint32_t *len,
|
||||
+ uint16_t num)
|
||||
+{
|
||||
+ struct rte_mbuf *cookie;
|
||||
+ uint16_t used_idx;
|
||||
+ uint16_t id;
|
||||
+ struct vring_packed_desc *desc;
|
||||
+ uint16_t i;
|
||||
+
|
||||
+ desc = vq->ring_packed.desc_packed;
|
||||
+
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ used_idx = vq->vq_used_cons_idx;
|
||||
+ if (!desc_is_used(&desc[used_idx], vq))
|
||||
+ return i;
|
||||
+ len[i] = desc[used_idx].len;
|
||||
+ id = desc[used_idx].id;
|
||||
+ cookie = (struct rte_mbuf *)vq->vq_descx[id].cookie;
|
||||
+ if (unlikely(cookie == NULL)) {
|
||||
+ PMD_DRV_LOG(ERR, "vring descriptor with no mbuf cookie at %u",
|
||||
+ vq->vq_used_cons_idx);
|
||||
+ break;
|
||||
+ }
|
||||
+ rte_prefetch0(cookie);
|
||||
+ rte_packet_prefetch(rte_pktmbuf_mtod(cookie, void *));
|
||||
+ rx_pkts[i] = cookie;
|
||||
+
|
||||
+ vq->vq_free_cnt++;
|
||||
+ vq->vq_used_cons_idx++;
|
||||
+ if (vq->vq_used_cons_idx >= vq->vq_nentries) {
|
||||
+ vq->vq_used_cons_idx -= vq->vq_nentries;
|
||||
+ vq->used_wrap_counter ^= 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return i;
|
||||
+}
|
||||
+
|
||||
static uint16_t
|
||||
virtqueue_dequeue_burst_rx(struct virtqueue *vq, struct rte_mbuf **rx_pkts,
|
||||
uint32_t *len, uint16_t num)
|
||||
@@ -350,6 +392,51 @@ virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct rte_mbuf *cookie)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+virtqueue_enqueue_recv_refill_packed(struct virtqueue *vq,
|
||||
+ struct rte_mbuf **cookie, uint16_t num)
|
||||
+{
|
||||
+ struct vring_packed_desc *start_dp = vq->ring_packed.desc_packed;
|
||||
+ uint16_t flags = VRING_DESC_F_WRITE | vq->avail_used_flags;
|
||||
+ struct virtio_hw *hw = vq->hw;
|
||||
+ struct vq_desc_extra *dxp;
|
||||
+ uint16_t idx;
|
||||
+ int i;
|
||||
+
|
||||
+ if (unlikely(vq->vq_free_cnt == 0))
|
||||
+ return -ENOSPC;
|
||||
+ if (unlikely(vq->vq_free_cnt < num))
|
||||
+ return -EMSGSIZE;
|
||||
+
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ idx = vq->vq_avail_idx;
|
||||
+ dxp = &vq->vq_descx[idx];
|
||||
+ dxp->cookie = (void *)cookie[i];
|
||||
+ dxp->ndescs = 1;
|
||||
+
|
||||
+ start_dp[idx].addr = VIRTIO_MBUF_ADDR(cookie[i], vq) +
|
||||
+ RTE_PKTMBUF_HEADROOM - hw->vtnet_hdr_size;
|
||||
+ start_dp[idx].len = cookie[i]->buf_len - RTE_PKTMBUF_HEADROOM
|
||||
+ + hw->vtnet_hdr_size;
|
||||
+
|
||||
+ vq->vq_desc_head_idx = dxp->next;
|
||||
+ if (vq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END)
|
||||
+ vq->vq_desc_tail_idx = vq->vq_desc_head_idx;
|
||||
+ rte_smp_wmb();
|
||||
+ start_dp[idx].flags = flags;
|
||||
+ if (++vq->vq_avail_idx >= vq->vq_nentries) {
|
||||
+ vq->vq_avail_idx -= vq->vq_nentries;
|
||||
+ vq->avail_wrap_counter ^= 1;
|
||||
+ vq->avail_used_flags =
|
||||
+ VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
|
||||
+ VRING_DESC_F_USED(!vq->avail_wrap_counter);
|
||||
+ flags = VRING_DESC_F_WRITE | vq->avail_used_flags;
|
||||
+ }
|
||||
+ }
|
||||
+ vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt - num);
|
||||
+ 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.
|
||||
@@ -801,7 +888,11 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx)
|
||||
break;
|
||||
|
||||
/* Enqueue allocated buffers */
|
||||
- error = virtqueue_enqueue_recv_refill(vq, m);
|
||||
+ if (vtpci_packed_queue(vq->hw))
|
||||
+ error = virtqueue_enqueue_recv_refill_packed(vq,
|
||||
+ &m, 1);
|
||||
+ else
|
||||
+ error = virtqueue_enqueue_recv_refill(vq, m);
|
||||
if (error) {
|
||||
rte_pktmbuf_free(m);
|
||||
break;
|
||||
@@ -809,7 +900,8 @@ virtio_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t queue_idx)
|
||||
nbufs++;
|
||||
}
|
||||
|
||||
- vq_update_avail_idx(vq);
|
||||
+ if (!vtpci_packed_queue(vq->hw))
|
||||
+ vq_update_avail_idx(vq);
|
||||
}
|
||||
|
||||
PMD_INIT_LOG(DEBUG, "Allocated %d bufs", nbufs);
|
||||
@@ -896,7 +988,10 @@ virtio_discard_rxbuf(struct virtqueue *vq, struct rte_mbuf *m)
|
||||
* Requeue the discarded mbuf. This should always be
|
||||
* successful since it was just dequeued.
|
||||
*/
|
||||
- error = virtqueue_enqueue_recv_refill(vq, m);
|
||||
+ if (vtpci_packed_queue(vq->hw))
|
||||
+ error = virtqueue_enqueue_recv_refill_packed(vq, &m, 1);
|
||||
+ else
|
||||
+ error = virtqueue_enqueue_recv_refill(vq, m);
|
||||
|
||||
if (unlikely(error)) {
|
||||
RTE_LOG(ERR, PMD, "cannot requeue discarded mbuf");
|
||||
@@ -1135,6 +1230,104 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
|
||||
return nb_rx;
|
||||
}
|
||||
|
||||
+uint16_t
|
||||
+virtio_recv_pkts_packed(void *rx_queue, struct rte_mbuf **rx_pkts,
|
||||
+ uint16_t nb_pkts)
|
||||
+{
|
||||
+ struct virtnet_rx *rxvq = rx_queue;
|
||||
+ struct virtqueue *vq = rxvq->vq;
|
||||
+ struct virtio_hw *hw = vq->hw;
|
||||
+ struct rte_mbuf *rxm, *new_mbuf;
|
||||
+ uint16_t num, nb_rx;
|
||||
+ uint32_t len[VIRTIO_MBUF_BURST_SZ];
|
||||
+ struct rte_mbuf *rcv_pkts[VIRTIO_MBUF_BURST_SZ];
|
||||
+ int error;
|
||||
+ uint32_t i, nb_enqueued;
|
||||
+ uint32_t hdr_size;
|
||||
+ struct virtio_net_hdr *hdr;
|
||||
+
|
||||
+ nb_rx = 0;
|
||||
+ if (unlikely(hw->started == 0))
|
||||
+ return nb_rx;
|
||||
+
|
||||
+ num = RTE_MIN(VIRTIO_MBUF_BURST_SZ, nb_pkts);
|
||||
+ if (likely(num > DESC_PER_CACHELINE))
|
||||
+ num = num - ((vq->vq_used_cons_idx + num) % DESC_PER_CACHELINE);
|
||||
+
|
||||
+ num = virtqueue_dequeue_burst_rx_packed(vq, rcv_pkts, len, num);
|
||||
+ PMD_RX_LOG(DEBUG, "dequeue:%d", num);
|
||||
+
|
||||
+ nb_enqueued = 0;
|
||||
+ hdr_size = hw->vtnet_hdr_size;
|
||||
+
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ rxm = rcv_pkts[i];
|
||||
+
|
||||
+ PMD_RX_LOG(DEBUG, "packet len:%d", len[i]);
|
||||
+
|
||||
+ if (unlikely(len[i] < hdr_size + ETHER_HDR_LEN)) {
|
||||
+ PMD_RX_LOG(ERR, "Packet drop");
|
||||
+ nb_enqueued++;
|
||||
+ virtio_discard_rxbuf(vq, rxm);
|
||||
+ rxvq->stats.errors++;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ rxm->port = rxvq->port_id;
|
||||
+ rxm->data_off = RTE_PKTMBUF_HEADROOM;
|
||||
+ rxm->ol_flags = 0;
|
||||
+ rxm->vlan_tci = 0;
|
||||
+
|
||||
+ rxm->pkt_len = (uint32_t)(len[i] - hdr_size);
|
||||
+ rxm->data_len = (uint16_t)(len[i] - hdr_size);
|
||||
+
|
||||
+ hdr = (struct virtio_net_hdr *)((char *)rxm->buf_addr +
|
||||
+ RTE_PKTMBUF_HEADROOM - hdr_size);
|
||||
+
|
||||
+ if (hw->vlan_strip)
|
||||
+ rte_vlan_strip(rxm);
|
||||
+
|
||||
+ if (hw->has_rx_offload && virtio_rx_offload(rxm, hdr) < 0) {
|
||||
+ virtio_discard_rxbuf(vq, rxm);
|
||||
+ rxvq->stats.errors++;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ virtio_rx_stats_updated(rxvq, rxm);
|
||||
+
|
||||
+ rx_pkts[nb_rx++] = rxm;
|
||||
+ }
|
||||
+
|
||||
+ rxvq->stats.packets += nb_rx;
|
||||
+
|
||||
+ /* Allocate new mbuf for the used descriptor */
|
||||
+ while (likely(!virtqueue_full(vq))) {
|
||||
+ new_mbuf = rte_mbuf_raw_alloc(rxvq->mpool);
|
||||
+ if (unlikely(new_mbuf == NULL)) {
|
||||
+ struct rte_eth_dev *dev =
|
||||
+ &rte_eth_devices[rxvq->port_id];
|
||||
+ dev->data->rx_mbuf_alloc_failed++;
|
||||
+ break;
|
||||
+ }
|
||||
+ error = virtqueue_enqueue_recv_refill_packed(vq, &new_mbuf, 1);
|
||||
+ if (unlikely(error)) {
|
||||
+ rte_pktmbuf_free(new_mbuf);
|
||||
+ break;
|
||||
+ }
|
||||
+ nb_enqueued++;
|
||||
+ }
|
||||
+
|
||||
+ if (likely(nb_enqueued)) {
|
||||
+ if (unlikely(virtqueue_kick_prepare_packed(vq))) {
|
||||
+ virtqueue_notify(vq);
|
||||
+ PMD_RX_LOG(DEBUG, "Notified");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return nb_rx;
|
||||
+}
|
||||
+
|
||||
+
|
||||
uint16_t
|
||||
virtio_recv_mergeable_pkts_inorder(void *rx_queue,
|
||||
struct rte_mbuf **rx_pkts,
|
||||
@@ -1493,6 +1686,182 @@ virtio_recv_mergeable_pkts(void *rx_queue,
|
||||
return nb_rx;
|
||||
}
|
||||
|
||||
+uint16_t
|
||||
+virtio_recv_mergeable_pkts_packed(void *rx_queue,
|
||||
+ struct rte_mbuf **rx_pkts,
|
||||
+ uint16_t nb_pkts)
|
||||
+{
|
||||
+ struct virtnet_rx *rxvq = rx_queue;
|
||||
+ struct virtqueue *vq = rxvq->vq;
|
||||
+ struct virtio_hw *hw = vq->hw;
|
||||
+ struct rte_mbuf *rxm;
|
||||
+ struct rte_mbuf *prev = NULL;
|
||||
+ uint16_t num, nb_rx = 0;
|
||||
+ uint32_t len[VIRTIO_MBUF_BURST_SZ];
|
||||
+ struct rte_mbuf *rcv_pkts[VIRTIO_MBUF_BURST_SZ];
|
||||
+ uint32_t nb_enqueued = 0;
|
||||
+ uint32_t seg_num = 0;
|
||||
+ uint32_t seg_res = 0;
|
||||
+ uint32_t hdr_size = hw->vtnet_hdr_size;
|
||||
+ int32_t i;
|
||||
+ int error;
|
||||
+
|
||||
+ if (unlikely(hw->started == 0))
|
||||
+ return nb_rx;
|
||||
+
|
||||
+
|
||||
+ num = nb_pkts;
|
||||
+ if (unlikely(num > VIRTIO_MBUF_BURST_SZ))
|
||||
+ num = VIRTIO_MBUF_BURST_SZ;
|
||||
+ if (likely(num > DESC_PER_CACHELINE))
|
||||
+ num = num - ((vq->vq_used_cons_idx + num) % DESC_PER_CACHELINE);
|
||||
+
|
||||
+ num = virtqueue_dequeue_burst_rx_packed(vq, rcv_pkts, len, num);
|
||||
+
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ struct virtio_net_hdr_mrg_rxbuf *header;
|
||||
+
|
||||
+ PMD_RX_LOG(DEBUG, "dequeue:%d", num);
|
||||
+ PMD_RX_LOG(DEBUG, "packet len:%d", len[i]);
|
||||
+
|
||||
+ rxm = rcv_pkts[i];
|
||||
+
|
||||
+ if (unlikely(len[i] < hdr_size + ETHER_HDR_LEN)) {
|
||||
+ PMD_RX_LOG(ERR, "Packet drop");
|
||||
+ nb_enqueued++;
|
||||
+ virtio_discard_rxbuf(vq, rxm);
|
||||
+ rxvq->stats.errors++;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ header = (struct virtio_net_hdr_mrg_rxbuf *)((char *)
|
||||
+ rxm->buf_addr + RTE_PKTMBUF_HEADROOM - hdr_size);
|
||||
+ seg_num = header->num_buffers;
|
||||
+
|
||||
+ if (seg_num == 0)
|
||||
+ seg_num = 1;
|
||||
+
|
||||
+ rxm->data_off = RTE_PKTMBUF_HEADROOM;
|
||||
+ rxm->nb_segs = seg_num;
|
||||
+ rxm->ol_flags = 0;
|
||||
+ rxm->vlan_tci = 0;
|
||||
+ rxm->pkt_len = (uint32_t)(len[i] - hdr_size);
|
||||
+ rxm->data_len = (uint16_t)(len[i] - hdr_size);
|
||||
+
|
||||
+ rxm->port = rxvq->port_id;
|
||||
+ rx_pkts[nb_rx] = rxm;
|
||||
+ prev = rxm;
|
||||
+
|
||||
+ if (hw->has_rx_offload &&
|
||||
+ virtio_rx_offload(rxm, &header->hdr) < 0) {
|
||||
+ virtio_discard_rxbuf(vq, rxm);
|
||||
+ rxvq->stats.errors++;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (hw->vlan_strip)
|
||||
+ rte_vlan_strip(rx_pkts[nb_rx]);
|
||||
+
|
||||
+ seg_res = seg_num - 1;
|
||||
+
|
||||
+ /* Merge remaining segments */
|
||||
+ while (seg_res != 0 && i < (num - 1)) {
|
||||
+ i++;
|
||||
+
|
||||
+ rxm = rcv_pkts[i];
|
||||
+ rxm->data_off = RTE_PKTMBUF_HEADROOM - hdr_size;
|
||||
+ rxm->pkt_len = (uint32_t)(len[i]);
|
||||
+ rxm->data_len = (uint16_t)(len[i]);
|
||||
+
|
||||
+ rx_pkts[nb_rx]->pkt_len += (uint32_t)(len[i]);
|
||||
+ rx_pkts[nb_rx]->data_len += (uint16_t)(len[i]);
|
||||
+
|
||||
+ if (prev)
|
||||
+ prev->next = rxm;
|
||||
+
|
||||
+ prev = rxm;
|
||||
+ seg_res -= 1;
|
||||
+ }
|
||||
+
|
||||
+ if (!seg_res) {
|
||||
+ virtio_rx_stats_updated(rxvq, rx_pkts[nb_rx]);
|
||||
+ nb_rx++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Last packet still need merge segments */
|
||||
+ while (seg_res != 0) {
|
||||
+ uint16_t rcv_cnt = RTE_MIN((uint16_t)seg_res,
|
||||
+ VIRTIO_MBUF_BURST_SZ);
|
||||
+ if (likely(vq->vq_free_cnt >= rcv_cnt)) {
|
||||
+ num = virtqueue_dequeue_burst_rx_packed(vq, rcv_pkts,
|
||||
+ len, rcv_cnt);
|
||||
+ uint16_t extra_idx = 0;
|
||||
+
|
||||
+ rcv_cnt = num;
|
||||
+
|
||||
+ while (extra_idx < rcv_cnt) {
|
||||
+ rxm = rcv_pkts[extra_idx];
|
||||
+
|
||||
+ rxm->data_off =
|
||||
+ RTE_PKTMBUF_HEADROOM - hdr_size;
|
||||
+ rxm->pkt_len = (uint32_t)(len[extra_idx]);
|
||||
+ rxm->data_len = (uint16_t)(len[extra_idx]);
|
||||
+
|
||||
+ prev->next = rxm;
|
||||
+ prev = rxm;
|
||||
+ rx_pkts[nb_rx]->pkt_len += len[extra_idx];
|
||||
+ rx_pkts[nb_rx]->data_len += len[extra_idx];
|
||||
+ extra_idx += 1;
|
||||
+ }
|
||||
+ seg_res -= rcv_cnt;
|
||||
+ if (!seg_res) {
|
||||
+ virtio_rx_stats_updated(rxvq, rx_pkts[nb_rx]);
|
||||
+ nb_rx++;
|
||||
+ }
|
||||
+ } else {
|
||||
+ PMD_RX_LOG(ERR,
|
||||
+ "No enough segments for packet.");
|
||||
+ if (prev)
|
||||
+ virtio_discard_rxbuf(vq, prev);
|
||||
+ rxvq->stats.errors++;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ rxvq->stats.packets += nb_rx;
|
||||
+
|
||||
+ /* Allocate new mbuf for the used descriptor */
|
||||
+ if (likely(!virtqueue_full(vq))) {
|
||||
+ /* free_cnt may include mrg descs */
|
||||
+ uint16_t free_cnt = vq->vq_free_cnt;
|
||||
+ struct rte_mbuf *new_pkts[free_cnt];
|
||||
+
|
||||
+ if (!rte_pktmbuf_alloc_bulk(rxvq->mpool, new_pkts, free_cnt)) {
|
||||
+ error = virtqueue_enqueue_recv_refill_packed(vq,
|
||||
+ new_pkts, free_cnt);
|
||||
+ if (unlikely(error)) {
|
||||
+ for (i = 0; i < free_cnt; i++)
|
||||
+ rte_pktmbuf_free(new_pkts[i]);
|
||||
+ }
|
||||
+ nb_enqueued += free_cnt;
|
||||
+ } else {
|
||||
+ struct rte_eth_dev *dev =
|
||||
+ &rte_eth_devices[rxvq->port_id];
|
||||
+ dev->data->rx_mbuf_alloc_failed += free_cnt;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (likely(nb_enqueued)) {
|
||||
+ if (unlikely(virtqueue_kick_prepare_packed(vq))) {
|
||||
+ virtqueue_notify(vq);
|
||||
+ PMD_RX_LOG(DEBUG, "Notified");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return nb_rx;
|
||||
+}
|
||||
+
|
||||
uint16_t
|
||||
virtio_xmit_pkts_packed(void *tx_queue, struct rte_mbuf **tx_pkts,
|
||||
uint16_t nb_pkts)
|
||||
diff --git a/drivers/net/virtio/virtqueue.c b/drivers/net/virtio/virtqueue.c
|
||||
index 56a77cc71..5b03f7a27 100644
|
||||
--- a/drivers/net/virtio/virtqueue.c
|
||||
+++ b/drivers/net/virtio/virtqueue.c
|
||||
@@ -54,9 +54,36 @@ virtqueue_detach_unused(struct virtqueue *vq)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+/* Flush used descs */
|
||||
+static void
|
||||
+virtqueue_rxvq_flush_packed(struct virtqueue *vq)
|
||||
+{
|
||||
+ struct vq_desc_extra *dxp;
|
||||
+ uint16_t i;
|
||||
+
|
||||
+ struct vring_packed_desc *descs = vq->ring_packed.desc_packed;
|
||||
+ int cnt = 0;
|
||||
+
|
||||
+ i = vq->vq_used_cons_idx;
|
||||
+ while (desc_is_used(&descs[i], vq) && cnt++ < vq->vq_nentries) {
|
||||
+ dxp = &vq->vq_descx[descs[i].id];
|
||||
+ if (dxp->cookie != NULL) {
|
||||
+ rte_pktmbuf_free(dxp->cookie);
|
||||
+ dxp->cookie = NULL;
|
||||
+ }
|
||||
+ vq->vq_free_cnt++;
|
||||
+ vq->vq_used_cons_idx++;
|
||||
+ if (vq->vq_used_cons_idx >= vq->vq_nentries) {
|
||||
+ vq->vq_used_cons_idx -= vq->vq_nentries;
|
||||
+ vq->used_wrap_counter ^= 1;
|
||||
+ }
|
||||
+ i = vq->vq_used_cons_idx;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* Flush the elements in the used ring. */
|
||||
-void
|
||||
-virtqueue_rxvq_flush(struct virtqueue *vq)
|
||||
+static void
|
||||
+virtqueue_rxvq_flush_split(struct virtqueue *vq)
|
||||
{
|
||||
struct virtnet_rx *rxq = &vq->rxq;
|
||||
struct virtio_hw *hw = vq->hw;
|
||||
@@ -102,3 +129,15 @@ virtqueue_rxvq_flush(struct virtqueue *vq)
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+/* Flush the elements in the used ring. */
|
||||
+void
|
||||
+virtqueue_rxvq_flush(struct virtqueue *vq)
|
||||
+{
|
||||
+ struct virtio_hw *hw = vq->hw;
|
||||
+
|
||||
+ if (vtpci_packed_queue(hw))
|
||||
+ virtqueue_rxvq_flush_packed(vq);
|
||||
+ else
|
||||
+ virtqueue_rxvq_flush_split(vq);
|
||||
+}
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,142 @@
|
||||
From d8d854a2f1814e10cf51ce88bf00b020167c772e Mon Sep 17 00:00:00 2001
|
||||
From: Jens Freimann <jfreimann@redhat.com>
|
||||
Date: Mon, 17 Dec 2018 22:31:36 +0100
|
||||
Subject: [PATCH 07/18] net/virtio: support packed queue in send command
|
||||
|
||||
[ upstream commit ec194c2f189525b2fb4be5604422a28ea5f08acd ]
|
||||
|
||||
Use packed virtqueue format when reading and writing descriptors
|
||||
to/from the ring.
|
||||
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit ec194c2f189525b2fb4be5604422a28ea5f08acd)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_ethdev.c | 96 ++++++++++++++++++++++++++++++
|
||||
1 file changed, 96 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
|
||||
index 4ef1da393..53773445b 100644
|
||||
--- a/drivers/net/virtio/virtio_ethdev.c
|
||||
+++ b/drivers/net/virtio/virtio_ethdev.c
|
||||
@@ -141,6 +141,96 @@ static const struct rte_virtio_xstats_name_off rte_virtio_txq_stat_strings[] = {
|
||||
|
||||
struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS];
|
||||
|
||||
+static struct virtio_pmd_ctrl *
|
||||
+virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
|
||||
+ int *dlen, int pkt_num)
|
||||
+{
|
||||
+ struct virtqueue *vq = cvq->vq;
|
||||
+ int head;
|
||||
+ struct vring_packed_desc *desc = vq->ring_packed.desc_packed;
|
||||
+ struct virtio_pmd_ctrl *result;
|
||||
+ int wrap_counter;
|
||||
+ uint16_t flags;
|
||||
+ int sum = 0;
|
||||
+ int k;
|
||||
+
|
||||
+ /*
|
||||
+ * Format is enforced in qemu code:
|
||||
+ * One TX packet for header;
|
||||
+ * At least one TX packet per argument;
|
||||
+ * One RX packet for ACK.
|
||||
+ */
|
||||
+ head = vq->vq_avail_idx;
|
||||
+ wrap_counter = vq->avail_wrap_counter;
|
||||
+ desc[head].flags = VRING_DESC_F_NEXT;
|
||||
+ desc[head].addr = cvq->virtio_net_hdr_mem;
|
||||
+ desc[head].len = sizeof(struct virtio_net_ctrl_hdr);
|
||||
+ vq->vq_free_cnt--;
|
||||
+ if (++vq->vq_avail_idx >= vq->vq_nentries) {
|
||||
+ vq->vq_avail_idx -= vq->vq_nentries;
|
||||
+ vq->avail_wrap_counter ^= 1;
|
||||
+ }
|
||||
+
|
||||
+ for (k = 0; k < pkt_num; k++) {
|
||||
+ desc[vq->vq_avail_idx].addr = cvq->virtio_net_hdr_mem
|
||||
+ + sizeof(struct virtio_net_ctrl_hdr)
|
||||
+ + sizeof(ctrl->status) + sizeof(uint8_t) * sum;
|
||||
+ desc[vq->vq_avail_idx].len = dlen[k];
|
||||
+ flags = VRING_DESC_F_NEXT;
|
||||
+ sum += dlen[k];
|
||||
+ vq->vq_free_cnt--;
|
||||
+ flags |= VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
|
||||
+ VRING_DESC_F_USED(!vq->avail_wrap_counter);
|
||||
+ desc[vq->vq_avail_idx].flags = flags;
|
||||
+ rte_smp_wmb();
|
||||
+ vq->vq_free_cnt--;
|
||||
+ if (++vq->vq_avail_idx >= vq->vq_nentries) {
|
||||
+ vq->vq_avail_idx -= vq->vq_nentries;
|
||||
+ vq->avail_wrap_counter ^= 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ desc[vq->vq_avail_idx].addr = cvq->virtio_net_hdr_mem
|
||||
+ + sizeof(struct virtio_net_ctrl_hdr);
|
||||
+ desc[vq->vq_avail_idx].len = sizeof(ctrl->status);
|
||||
+ flags = VRING_DESC_F_WRITE;
|
||||
+ flags |= VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
|
||||
+ VRING_DESC_F_USED(!vq->avail_wrap_counter);
|
||||
+ desc[vq->vq_avail_idx].flags = flags;
|
||||
+ flags = VRING_DESC_F_NEXT;
|
||||
+ flags |= VRING_DESC_F_AVAIL(wrap_counter) |
|
||||
+ VRING_DESC_F_USED(!wrap_counter);
|
||||
+ desc[head].flags = flags;
|
||||
+ rte_smp_wmb();
|
||||
+
|
||||
+ vq->vq_free_cnt--;
|
||||
+ if (++vq->vq_avail_idx >= vq->vq_nentries) {
|
||||
+ vq->vq_avail_idx -= vq->vq_nentries;
|
||||
+ vq->avail_wrap_counter ^= 1;
|
||||
+ }
|
||||
+
|
||||
+ virtqueue_notify(vq);
|
||||
+
|
||||
+ /* wait for used descriptors in virtqueue */
|
||||
+ do {
|
||||
+ rte_rmb();
|
||||
+ usleep(100);
|
||||
+ } while (!desc_is_used(&desc[head], vq));
|
||||
+
|
||||
+ /* now get used descriptors */
|
||||
+ while (desc_is_used(&desc[vq->vq_used_cons_idx], vq)) {
|
||||
+ vq->vq_free_cnt++;
|
||||
+ if (++vq->vq_used_cons_idx >= vq->vq_nentries) {
|
||||
+ vq->vq_used_cons_idx -= vq->vq_nentries;
|
||||
+ vq->used_wrap_counter ^= 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ result = cvq->virtio_net_hdr_mz->addr;
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
|
||||
int *dlen, int pkt_num)
|
||||
@@ -174,6 +264,11 @@ virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
|
||||
memcpy(cvq->virtio_net_hdr_mz->addr, ctrl,
|
||||
sizeof(struct virtio_pmd_ctrl));
|
||||
|
||||
+ if (vtpci_packed_queue(vq->hw)) {
|
||||
+ result = virtio_pq_send_command(cvq, ctrl, dlen, pkt_num);
|
||||
+ goto out_unlock;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Format is enforced in qemu code:
|
||||
* One TX packet for header;
|
||||
@@ -245,6 +340,7 @@ virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
|
||||
|
||||
result = cvq->virtio_net_hdr_mz->addr;
|
||||
|
||||
+out_unlock:
|
||||
rte_spinlock_unlock(&cvq->lock);
|
||||
return result->status;
|
||||
}
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,139 @@
|
||||
From 0cdcdd50e4cbb88737abfee1e545019500f11e38 Mon Sep 17 00:00:00 2001
|
||||
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
|
||||
Date: Mon, 17 Dec 2018 22:31:37 +0100
|
||||
Subject: [PATCH] net/virtio-user: add option to use packed queues
|
||||
|
||||
[ upstream commit 34f3966c7f81f947e9eebb347dec6a9f68eec4e6 ]
|
||||
|
||||
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
|
||||
|
||||
Add option to enable packed queue support for virtio-user
|
||||
devices.
|
||||
|
||||
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit 34f3966c7f81f947e9eebb347dec6a9f68eec4e6)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
.../net/virtio/virtio_user/virtio_user_dev.c | 20 ++++++++++++++-----
|
||||
.../net/virtio/virtio_user/virtio_user_dev.h | 2 +-
|
||||
drivers/net/virtio/virtio_user_ethdev.c | 14 ++++++++++++-
|
||||
3 files changed, 29 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
index f0051f887..7d0acaeb7 100644
|
||||
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* SPDX-License-Identifier: BSD-3-Clause
|
||||
+/* SPDX-License-Identifier: BSD-1-Clause
|
||||
* Copyright(c) 2010-2016 Intel Corporation
|
||||
*/
|
||||
|
||||
@@ -58,6 +58,8 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel)
|
||||
|
||||
state.index = queue_sel;
|
||||
state.num = 0; /* no reservation */
|
||||
+ if (dev->features & (1ULL << VIRTIO_F_RING_PACKED))
|
||||
+ state.num |= (1 << 15);
|
||||
dev->ops->send_request(dev, VHOST_USER_SET_VRING_BASE, &state);
|
||||
|
||||
dev->ops->send_request(dev, VHOST_USER_SET_VRING_ADDR, &addr);
|
||||
@@ -407,12 +409,13 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
|
||||
1ULL << VIRTIO_NET_F_GUEST_TSO4 | \
|
||||
1ULL << VIRTIO_NET_F_GUEST_TSO6 | \
|
||||
1ULL << VIRTIO_F_IN_ORDER | \
|
||||
- 1ULL << VIRTIO_F_VERSION_1)
|
||||
+ 1ULL << VIRTIO_F_VERSION_1 | \
|
||||
+ 1ULL << VIRTIO_F_RING_PACKED)
|
||||
|
||||
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 server, int mrg_rxbuf, int in_order)
|
||||
+ int server, int mrg_rxbuf, int in_order, int packed_vq)
|
||||
{
|
||||
pthread_mutex_init(&dev->mutex, NULL);
|
||||
snprintf(dev->path, PATH_MAX, "%s", path);
|
||||
@@ -465,10 +468,17 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
|
||||
if (!in_order)
|
||||
dev->unsupported_features |= (1ull << VIRTIO_F_IN_ORDER);
|
||||
|
||||
- if (dev->mac_specified)
|
||||
- dev->frontend_features |= (1ull << VIRTIO_NET_F_MAC);
|
||||
+ if (packed_vq)
|
||||
+ dev->device_features |= (1ull << VIRTIO_F_RING_PACKED);
|
||||
else
|
||||
+ dev->device_features &= ~(1ull << VIRTIO_F_RING_PACKED);
|
||||
+
|
||||
+ if (dev->mac_specified) {
|
||||
+ dev->device_features |= (1ull << VIRTIO_NET_F_MAC);
|
||||
+ } else {
|
||||
+ dev->device_features &= ~(1ull << VIRTIO_NET_F_MAC);
|
||||
dev->unsupported_features |= (1ull << VIRTIO_NET_F_MAC);
|
||||
+ }
|
||||
|
||||
if (cq) {
|
||||
/* device does not really need to know anything about CQ,
|
||||
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h
|
||||
index 3e3a7b787..67a9c01ac 100644
|
||||
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
|
||||
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
|
||||
@@ -50,7 +50,7 @@ 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 server, int mrg_rxbuf, int in_order);
|
||||
+ int server, int mrg_rxbuf, int in_order, int packed_vq);
|
||||
void virtio_user_dev_uninit(struct virtio_user_dev *dev);
|
||||
void virtio_user_handle_cq(struct virtio_user_dev *dev, uint16_t queue_idx);
|
||||
uint8_t virtio_user_handle_mq(struct virtio_user_dev *dev, uint16_t q_pairs);
|
||||
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
|
||||
index 5781c0948..daad8f452 100644
|
||||
--- a/drivers/net/virtio/virtio_user_ethdev.c
|
||||
+++ b/drivers/net/virtio/virtio_user_ethdev.c
|
||||
@@ -361,6 +361,8 @@ static const char *valid_args[] = {
|
||||
VIRTIO_USER_ARG_MRG_RXBUF,
|
||||
#define VIRTIO_USER_ARG_IN_ORDER "in_order"
|
||||
VIRTIO_USER_ARG_IN_ORDER,
|
||||
+#define VIRTIO_USER_ARG_PACKED_VQ "packed_vq"
|
||||
+ VIRTIO_USER_ARG_PACKED_VQ,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -468,6 +470,7 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev)
|
||||
char *ifname = NULL;
|
||||
char *mac_addr = NULL;
|
||||
int ret = -1;
|
||||
+ uint64_t packed_vq = 0;
|
||||
|
||||
if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
|
||||
const char *name = rte_vdev_device_name(dev);
|
||||
@@ -571,6 +574,15 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev)
|
||||
cq = 1;
|
||||
}
|
||||
|
||||
+ if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_PACKED_VQ) == 1) {
|
||||
+ if (rte_kvargs_process(kvlist, VIRTIO_USER_ARG_PACKED_VQ,
|
||||
+ &get_integer_arg, &packed_vq) < 0) {
|
||||
+ PMD_INIT_LOG(ERR, "error to parse %s",
|
||||
+ VIRTIO_USER_ARG_PACKED_VQ);
|
||||
+ goto end;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (queues > 1 && cq == 0) {
|
||||
PMD_INIT_LOG(ERR, "multi-q requires ctrl-q");
|
||||
goto end;
|
||||
@@ -610,7 +622,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, server_mode,
|
||||
- mrg_rxbuf, in_order) < 0) {
|
||||
+ mrg_rxbuf, in_order, packed_vq) < 0) {
|
||||
PMD_INIT_LOG(ERR, "virtio_user_dev_init fails");
|
||||
virtio_user_eth_dev_free(eth_dev);
|
||||
goto end;
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,44 @@
|
||||
From f5302062cbc98b3b8b1002cc48e7125a48ead96c Mon Sep 17 00:00:00 2001
|
||||
From: Jens Freimann <jfreimann@redhat.com>
|
||||
Date: Mon, 17 Dec 2018 22:31:38 +0100
|
||||
Subject: [PATCH 09/18] net/virtio-user: fail if cq used with packed vq
|
||||
|
||||
[ upstream commit 07dd7e250d0128bf1edfd73e9d83bde09cdb11e9 ]
|
||||
|
||||
Until we have support for control virtqueues let's disable it and
|
||||
fail device initalization if specified as a parameter.
|
||||
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit 07dd7e250d0128bf1edfd73e9d83bde09cdb11e9)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_user/virtio_user_dev.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
index 77cec1d3c..2f75091d5 100644
|
||||
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
@@ -467,10 +467,16 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
|
||||
if (!in_order)
|
||||
dev->unsupported_features |= (1ull << VIRTIO_F_IN_ORDER);
|
||||
|
||||
- if (packed_vq)
|
||||
+ if (packed_vq) {
|
||||
+ if (cq) {
|
||||
+ PMD_INIT_LOG(ERR, "control vq not supported yet with "
|
||||
+ "packed virtqueues\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
dev->device_features |= (1ull << VIRTIO_F_RING_PACKED);
|
||||
- else
|
||||
+ } else {
|
||||
dev->device_features &= ~(1ull << VIRTIO_F_RING_PACKED);
|
||||
+ }
|
||||
|
||||
if (dev->mac_specified) {
|
||||
dev->device_features |= (1ull << VIRTIO_NET_F_MAC);
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,45 @@
|
||||
From d1b8c268219498c865511b375b0c0c89244046f9 Mon Sep 17 00:00:00 2001
|
||||
From: Jens Freimann <jfreimann@redhat.com>
|
||||
Date: Mon, 17 Dec 2018 22:31:39 +0100
|
||||
Subject: [PATCH 10/18] net/virtio: enable packed virtqueues by default
|
||||
|
||||
[ upstream commit aea29aa5d37b40080cfc1f9a1acba239bf03922f ]
|
||||
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit aea29aa5d37b40080cfc1f9a1acba239bf03922f)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_ethdev.h | 1 +
|
||||
drivers/net/virtio/virtio_user/virtio_user_dev.c | 3 ++-
|
||||
2 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
|
||||
index 88b8c42a3..364ecbb50 100644
|
||||
--- a/drivers/net/virtio/virtio_ethdev.h
|
||||
+++ b/drivers/net/virtio/virtio_ethdev.h
|
||||
@@ -34,6 +34,7 @@
|
||||
1u << VIRTIO_RING_F_INDIRECT_DESC | \
|
||||
1ULL << VIRTIO_F_VERSION_1 | \
|
||||
1ULL << VIRTIO_F_IN_ORDER | \
|
||||
+ 1ULL << VIRTIO_F_RING_PACKED | \
|
||||
1ULL << VIRTIO_F_IOMMU_PLATFORM)
|
||||
|
||||
#define VIRTIO_PMD_SUPPORTED_GUEST_FEATURES \
|
||||
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
index 2f75091d5..5999b7d9d 100644
|
||||
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
@@ -410,7 +410,8 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
|
||||
1ULL << VIRTIO_NET_F_GUEST_TSO6 | \
|
||||
1ULL << VIRTIO_F_IN_ORDER | \
|
||||
1ULL << VIRTIO_F_VERSION_1 | \
|
||||
- 1ULL << VIRTIO_F_RING_PACKED)
|
||||
+ 1ULL << VIRTIO_F_RING_PACKED | \
|
||||
+ 1ULL << VIRTIO_RING_F_EVENT_IDX)
|
||||
|
||||
int
|
||||
virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,33 @@
|
||||
From 440731f30a1257c3318badfcf17f5ab9e5085317 Mon Sep 17 00:00:00 2001
|
||||
From: Jens Freimann <jfreimann@redhat.com>
|
||||
Date: Thu, 20 Dec 2018 11:56:24 +0100
|
||||
Subject: [PATCH 11/18] net/virtio: avoid double accounting of bytes
|
||||
|
||||
[ upstream commit 517ad3e018e31ab2596d1ece5369894703c850c2 ]
|
||||
|
||||
Accounting of bytes was moved to a common function, so at the moment we do
|
||||
it twice. This patches fixes it for sending packets with packed virtqueues.
|
||||
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit 517ad3e018e31ab2596d1ece5369894703c850c2)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_rxtx.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
|
||||
index 0bcf3b08a..50eb4c694 100644
|
||||
--- a/drivers/net/virtio/virtio_rxtx.c
|
||||
+++ b/drivers/net/virtio/virtio_rxtx.c
|
||||
@@ -1931,7 +1931,6 @@ virtio_xmit_pkts_packed(void *tx_queue, struct rte_mbuf **tx_pkts,
|
||||
/* Enqueue Packet buffers */
|
||||
virtqueue_enqueue_xmit_packed(txvq, txm, slots, can_push);
|
||||
|
||||
- txvq->stats.bytes += txm->pkt_len;
|
||||
virtio_update_packet_stats(&txvq->stats, txm);
|
||||
}
|
||||
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,85 @@
|
||||
From ec53a1992df973607cbb10db6a0816ed2ef498dd Mon Sep 17 00:00:00 2001
|
||||
From: Tiwei Bie <tiwei.bie@intel.com>
|
||||
Date: Thu, 3 Jan 2019 10:40:06 +0800
|
||||
Subject: [PATCH] net/virtio-user: fix packed vq option parsing
|
||||
|
||||
[ upstream commit 9070f88b81dab42739fb169265e3ea727e47dfa2 ]
|
||||
|
||||
Add the RING_PACKED feature to dev->unsupported_features
|
||||
when it's disabled, and add the missing packed vq param
|
||||
string. And also revert the unexpected change to MAC option
|
||||
introduced when adding packed vq option.
|
||||
|
||||
Fixes: 34f3966c7f81 ("net/virtio-user: add option to use packed queues")
|
||||
|
||||
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit 9070f88b81dab42739fb169265e3ea727e47dfa2)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_user/virtio_user_dev.c | 11 ++++-------
|
||||
drivers/net/virtio/virtio_user_ethdev.c | 7 ++++---
|
||||
2 files changed, 8 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
index 811b95c45..426682c93 100644
|
||||
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
@@ -475,17 +475,14 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
|
||||
"packed virtqueues\n");
|
||||
return -1;
|
||||
}
|
||||
- dev->device_features |= (1ull << VIRTIO_F_RING_PACKED);
|
||||
} else {
|
||||
- dev->device_features &= ~(1ull << VIRTIO_F_RING_PACKED);
|
||||
+ dev->unsupported_features |= (1ull << VIRTIO_F_RING_PACKED);
|
||||
}
|
||||
|
||||
- if (dev->mac_specified) {
|
||||
- dev->device_features |= (1ull << VIRTIO_NET_F_MAC);
|
||||
- } else {
|
||||
- dev->device_features &= ~(1ull << VIRTIO_NET_F_MAC);
|
||||
+ if (dev->mac_specified)
|
||||
+ dev->frontend_features |= (1ull << VIRTIO_NET_F_MAC);
|
||||
+ else
|
||||
dev->unsupported_features |= (1ull << VIRTIO_NET_F_MAC);
|
||||
- }
|
||||
|
||||
if (cq) {
|
||||
/* device does not really need to know anything about CQ,
|
||||
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
|
||||
index daad8f452..a2911febf 100644
|
||||
--- a/drivers/net/virtio/virtio_user_ethdev.c
|
||||
+++ b/drivers/net/virtio/virtio_user_ethdev.c
|
||||
@@ -361,7 +361,7 @@ static const char *valid_args[] = {
|
||||
VIRTIO_USER_ARG_MRG_RXBUF,
|
||||
#define VIRTIO_USER_ARG_IN_ORDER "in_order"
|
||||
VIRTIO_USER_ARG_IN_ORDER,
|
||||
-#define VIRTIO_USER_ARG_PACKED_VQ "packed_vq"
|
||||
+#define VIRTIO_USER_ARG_PACKED_VQ "packed_vq"
|
||||
VIRTIO_USER_ARG_PACKED_VQ,
|
||||
NULL
|
||||
};
|
||||
@@ -466,11 +466,11 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev)
|
||||
uint64_t server_mode = VIRTIO_USER_DEF_SERVER_MODE;
|
||||
uint64_t mrg_rxbuf = 1;
|
||||
uint64_t in_order = 1;
|
||||
+ uint64_t packed_vq = 0;
|
||||
char *path = NULL;
|
||||
char *ifname = NULL;
|
||||
char *mac_addr = NULL;
|
||||
int ret = -1;
|
||||
- uint64_t packed_vq = 0;
|
||||
|
||||
if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
|
||||
const char *name = rte_vdev_device_name(dev);
|
||||
@@ -698,4 +698,5 @@ RTE_PMD_REGISTER_PARAM_STRING(net_virtio_user,
|
||||
"iface=<string> "
|
||||
"server=<0|1> "
|
||||
"mrg_rxbuf=<0|1> "
|
||||
- "in_order=<0|1>");
|
||||
+ "in_order=<0|1> "
|
||||
+ "packed_vq=<0|1>");
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,36 @@
|
||||
From b6da125960fb1fb017427af5910b43ac81586850 Mon Sep 17 00:00:00 2001
|
||||
From: Tiwei Bie <tiwei.bie@intel.com>
|
||||
Date: Thu, 3 Jan 2019 10:40:07 +0800
|
||||
Subject: [PATCH 13/18] net/virtio-user: fix supported features list
|
||||
|
||||
[ upstream commit 8532a0fcd8f2cf3a5d3189b453bd90a69991b1b1 ]
|
||||
|
||||
Currently virtio-user doesn't support event idx.
|
||||
|
||||
Fixes: aea29aa5d37b ("net/virtio: enable packed virtqueues by default")
|
||||
|
||||
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit 8532a0fcd8f2cf3a5d3189b453bd90a69991b1b1)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_user/virtio_user_dev.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
index c4e026096..77341f895 100644
|
||||
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
@@ -410,8 +410,7 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
|
||||
1ULL << VIRTIO_NET_F_GUEST_TSO6 | \
|
||||
1ULL << VIRTIO_F_IN_ORDER | \
|
||||
1ULL << VIRTIO_F_VERSION_1 | \
|
||||
- 1ULL << VIRTIO_F_RING_PACKED | \
|
||||
- 1ULL << VIRTIO_RING_F_EVENT_IDX)
|
||||
+ 1ULL << VIRTIO_F_RING_PACKED)
|
||||
|
||||
int
|
||||
virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,98 @@
|
||||
From 82b43dd199d5492527b73002d4c3b009a98ca7a0 Mon Sep 17 00:00:00 2001
|
||||
From: Jens Freimann <jfreimann@redhat.com>
|
||||
Date: Fri, 11 Jan 2019 10:39:28 +0100
|
||||
Subject: [PATCH 14/18] net/virtio: check head desc with correct wrap counter
|
||||
|
||||
[ upstream commit a4270ea4ff79b46280dd542f4ab3eb45f8c9685a ]
|
||||
|
||||
In virtio_pq_send_command() we check for a used descriptor
|
||||
and wait in an idle loop until it becomes used. We can't use
|
||||
vq->used_wrap_counter here to check for the first descriptor
|
||||
we made available because the ring could have wrapped. Let's use
|
||||
the used_wrap_counter that matches the state of the head descriptor.
|
||||
|
||||
Fixes: ec194c2f1895 ("net/virtio: support packed queue in send command")
|
||||
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit a4270ea4ff79b46280dd542f4ab3eb45f8c9685a)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_ethdev.c | 11 ++++++-----
|
||||
drivers/net/virtio/virtqueue.h | 10 ++++++++--
|
||||
2 files changed, 14 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
|
||||
index 53773445b..7bd38a292 100644
|
||||
--- a/drivers/net/virtio/virtio_ethdev.c
|
||||
+++ b/drivers/net/virtio/virtio_ethdev.c
|
||||
@@ -149,7 +149,7 @@ virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
|
||||
int head;
|
||||
struct vring_packed_desc *desc = vq->ring_packed.desc_packed;
|
||||
struct virtio_pmd_ctrl *result;
|
||||
- int wrap_counter;
|
||||
+ bool avail_wrap_counter, used_wrap_counter;
|
||||
uint16_t flags;
|
||||
int sum = 0;
|
||||
int k;
|
||||
@@ -161,7 +161,8 @@ virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
|
||||
* One RX packet for ACK.
|
||||
*/
|
||||
head = vq->vq_avail_idx;
|
||||
- wrap_counter = vq->avail_wrap_counter;
|
||||
+ avail_wrap_counter = vq->avail_wrap_counter;
|
||||
+ used_wrap_counter = vq->used_wrap_counter;
|
||||
desc[head].flags = VRING_DESC_F_NEXT;
|
||||
desc[head].addr = cvq->virtio_net_hdr_mem;
|
||||
desc[head].len = sizeof(struct virtio_net_ctrl_hdr);
|
||||
@@ -199,8 +200,8 @@ virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
|
||||
VRING_DESC_F_USED(!vq->avail_wrap_counter);
|
||||
desc[vq->vq_avail_idx].flags = flags;
|
||||
flags = VRING_DESC_F_NEXT;
|
||||
- flags |= VRING_DESC_F_AVAIL(wrap_counter) |
|
||||
- VRING_DESC_F_USED(!wrap_counter);
|
||||
+ flags |= VRING_DESC_F_AVAIL(avail_wrap_counter) |
|
||||
+ VRING_DESC_F_USED(!avail_wrap_counter);
|
||||
desc[head].flags = flags;
|
||||
rte_smp_wmb();
|
||||
|
||||
@@ -216,7 +217,7 @@ virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
|
||||
do {
|
||||
rte_rmb();
|
||||
usleep(100);
|
||||
- } while (!desc_is_used(&desc[head], vq));
|
||||
+ } while (!__desc_is_used(&desc[head], used_wrap_counter));
|
||||
|
||||
/* now get used descriptors */
|
||||
while (desc_is_used(&desc[vq->vq_used_cons_idx], vq)) {
|
||||
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
|
||||
index b142fd488..75f5782bc 100644
|
||||
--- a/drivers/net/virtio/virtqueue.h
|
||||
+++ b/drivers/net/virtio/virtqueue.h
|
||||
@@ -256,7 +256,7 @@ struct virtio_tx_region {
|
||||
};
|
||||
|
||||
static inline int
|
||||
-desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
|
||||
+__desc_is_used(struct vring_packed_desc *desc, bool wrap_counter)
|
||||
{
|
||||
uint16_t used, avail, flags;
|
||||
|
||||
@@ -264,7 +264,13 @@ desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
|
||||
used = !!(flags & VRING_DESC_F_USED(1));
|
||||
avail = !!(flags & VRING_DESC_F_AVAIL(1));
|
||||
|
||||
- return avail == used && used == vq->used_wrap_counter;
|
||||
+ return avail == used && used == wrap_counter;
|
||||
+}
|
||||
+
|
||||
+static inline int
|
||||
+desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
|
||||
+{
|
||||
+ return __desc_is_used(desc, vq->used_wrap_counter);
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
2.21.0
|
||||
|
277
SOURCES/0015-net-virtio-user-support-control-VQ-for-packed.patch
Normal file
277
SOURCES/0015-net-virtio-user-support-control-VQ-for-packed.patch
Normal file
@ -0,0 +1,277 @@
|
||||
From 74bbcd238093edc81b1a1f0b9b6e0d3c3fe32584 Mon Sep 17 00:00:00 2001
|
||||
From: Jens Freimann <jfreimann@redhat.com>
|
||||
Date: Fri, 11 Jan 2019 10:39:29 +0100
|
||||
Subject: [PATCH] net/virtio-user: support control VQ for packed
|
||||
|
||||
[ upstream commit 48a4464029a7f76dfb2c1f09146a391917b075e5 ]
|
||||
|
||||
Add support to virtio-user for control virtqueues.
|
||||
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit 48a4464029a7f76dfb2c1f09146a391917b075e5)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
.../net/virtio/virtio_user/virtio_user_dev.c | 102 ++++++++++++++++--
|
||||
.../net/virtio/virtio_user/virtio_user_dev.h | 15 ++-
|
||||
drivers/net/virtio/virtio_user_ethdev.c | 56 +++++++++-
|
||||
3 files changed, 157 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
index 2caaaad5f..83d3fb531 100644
|
||||
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
@@ -43,15 +43,26 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel)
|
||||
struct vhost_vring_file file;
|
||||
struct vhost_vring_state state;
|
||||
struct vring *vring = &dev->vrings[queue_sel];
|
||||
+ struct vring_packed *pq_vring = &dev->packed_vrings[queue_sel];
|
||||
struct vhost_vring_addr addr = {
|
||||
.index = queue_sel,
|
||||
- .desc_user_addr = (uint64_t)(uintptr_t)vring->desc,
|
||||
- .avail_user_addr = (uint64_t)(uintptr_t)vring->avail,
|
||||
- .used_user_addr = (uint64_t)(uintptr_t)vring->used,
|
||||
.log_guest_addr = 0,
|
||||
.flags = 0, /* disable log */
|
||||
};
|
||||
|
||||
+ if (dev->features & (1ULL << VIRTIO_F_RING_PACKED)) {
|
||||
+ addr.desc_user_addr =
|
||||
+ (uint64_t)(uintptr_t)pq_vring->desc_packed;
|
||||
+ addr.avail_user_addr =
|
||||
+ (uint64_t)(uintptr_t)pq_vring->driver_event;
|
||||
+ addr.used_user_addr =
|
||||
+ (uint64_t)(uintptr_t)pq_vring->device_event;
|
||||
+ } else {
|
||||
+ addr.desc_user_addr = (uint64_t)(uintptr_t)vring->desc;
|
||||
+ addr.avail_user_addr = (uint64_t)(uintptr_t)vring->avail;
|
||||
+ addr.used_user_addr = (uint64_t)(uintptr_t)vring->used;
|
||||
+ }
|
||||
+
|
||||
state.index = queue_sel;
|
||||
state.num = vring->num;
|
||||
dev->ops->send_request(dev, VHOST_USER_SET_VRING_NUM, &state);
|
||||
@@ -468,15 +479,8 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
|
||||
if (!in_order)
|
||||
dev->unsupported_features |= (1ull << VIRTIO_F_IN_ORDER);
|
||||
|
||||
- if (packed_vq) {
|
||||
- if (cq) {
|
||||
- PMD_INIT_LOG(ERR, "control vq not supported yet with "
|
||||
- "packed virtqueues\n");
|
||||
- return -1;
|
||||
- }
|
||||
- } else {
|
||||
+ if (!packed_vq)
|
||||
dev->unsupported_features |= (1ull << VIRTIO_F_RING_PACKED);
|
||||
- }
|
||||
|
||||
if (dev->mac_specified)
|
||||
dev->frontend_features |= (1ull << VIRTIO_NET_F_MAC);
|
||||
@@ -621,6 +625,82 @@ virtio_user_handle_ctrl_msg(struct virtio_user_dev *dev, struct vring *vring,
|
||||
return n_descs;
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+desc_is_avail(struct vring_packed_desc *desc, bool wrap_counter)
|
||||
+{
|
||||
+ return wrap_counter == !!(desc->flags & VRING_DESC_F_AVAIL(1)) &&
|
||||
+ wrap_counter != !!(desc->flags & VRING_DESC_F_USED(1));
|
||||
+}
|
||||
+
|
||||
+static uint32_t
|
||||
+virtio_user_handle_ctrl_msg_pq(struct virtio_user_dev *dev,
|
||||
+ struct vring_packed *vring,
|
||||
+ uint16_t idx_hdr)
|
||||
+{
|
||||
+ struct virtio_net_ctrl_hdr *hdr;
|
||||
+ virtio_net_ctrl_ack status = ~0;
|
||||
+ uint16_t idx_data, idx_status;
|
||||
+ /* initialize to one, header is first */
|
||||
+ uint32_t n_descs = 1;
|
||||
+
|
||||
+ /* locate desc for header, data, and status */
|
||||
+ idx_data = idx_hdr + 1;
|
||||
+ if (idx_data >= dev->queue_size)
|
||||
+ idx_data -= dev->queue_size;
|
||||
+
|
||||
+ n_descs++;
|
||||
+
|
||||
+ idx_status = idx_data;
|
||||
+ while (vring->desc_packed[idx_status].flags & VRING_DESC_F_NEXT) {
|
||||
+ idx_status++;
|
||||
+ if (idx_status >= dev->queue_size)
|
||||
+ idx_status -= dev->queue_size;
|
||||
+ n_descs++;
|
||||
+ }
|
||||
+
|
||||
+ hdr = (void *)(uintptr_t)vring->desc_packed[idx_hdr].addr;
|
||||
+ if (hdr->class == VIRTIO_NET_CTRL_MQ &&
|
||||
+ hdr->cmd == VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET) {
|
||||
+ uint16_t queues;
|
||||
+
|
||||
+ queues = *(uint16_t *)(uintptr_t)
|
||||
+ vring->desc_packed[idx_data].addr;
|
||||
+ status = virtio_user_handle_mq(dev, queues);
|
||||
+ }
|
||||
+
|
||||
+ /* Update status */
|
||||
+ *(virtio_net_ctrl_ack *)(uintptr_t)
|
||||
+ vring->desc_packed[idx_status].addr = status;
|
||||
+
|
||||
+ return n_descs;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+virtio_user_handle_cq_packed(struct virtio_user_dev *dev, uint16_t queue_idx)
|
||||
+{
|
||||
+ struct virtio_user_queue *vq = &dev->packed_queues[queue_idx];
|
||||
+ struct vring_packed *vring = &dev->packed_vrings[queue_idx];
|
||||
+ uint16_t id, n_descs;
|
||||
+
|
||||
+ while (desc_is_avail(&vring->desc_packed[vq->used_idx],
|
||||
+ vq->used_wrap_counter)) {
|
||||
+ id = vring->desc_packed[vq->used_idx].id;
|
||||
+
|
||||
+ n_descs = virtio_user_handle_ctrl_msg_pq(dev, vring, id);
|
||||
+
|
||||
+ do {
|
||||
+ vring->desc_packed[vq->used_idx].flags =
|
||||
+ VRING_DESC_F_AVAIL(vq->used_wrap_counter) |
|
||||
+ VRING_DESC_F_USED(vq->used_wrap_counter);
|
||||
+ if (++vq->used_idx >= dev->queue_size) {
|
||||
+ vq->used_idx -= dev->queue_size;
|
||||
+ vq->used_wrap_counter ^= 1;
|
||||
+ }
|
||||
+ n_descs--;
|
||||
+ } while (n_descs);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void
|
||||
virtio_user_handle_cq(struct virtio_user_dev *dev, uint16_t queue_idx)
|
||||
{
|
||||
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h
|
||||
index 67a9c01ac..c6c2f7d6e 100644
|
||||
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
|
||||
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
|
||||
@@ -11,6 +11,12 @@
|
||||
#include "../virtio_ring.h"
|
||||
#include "vhost.h"
|
||||
|
||||
+struct virtio_user_queue {
|
||||
+ uint16_t used_idx;
|
||||
+ bool avail_wrap_counter;
|
||||
+ bool used_wrap_counter;
|
||||
+};
|
||||
+
|
||||
struct virtio_user_dev {
|
||||
/* for vhost_user backend */
|
||||
int vhostfd;
|
||||
@@ -39,7 +45,12 @@ struct virtio_user_dev {
|
||||
uint16_t port_id;
|
||||
uint8_t mac_addr[ETHER_ADDR_LEN];
|
||||
char path[PATH_MAX];
|
||||
- struct vring vrings[VIRTIO_MAX_VIRTQUEUES];
|
||||
+ union {
|
||||
+ struct vring vrings[VIRTIO_MAX_VIRTQUEUES];
|
||||
+ struct vring_packed packed_vrings[VIRTIO_MAX_VIRTQUEUES];
|
||||
+ };
|
||||
+ struct virtio_user_queue packed_queues[VIRTIO_MAX_VIRTQUEUES];
|
||||
+
|
||||
struct virtio_user_backend_ops *ops;
|
||||
pthread_mutex_t mutex;
|
||||
bool started;
|
||||
@@ -53,5 +64,7 @@ int virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
|
||||
int server, int mrg_rxbuf, int in_order, int packed_vq);
|
||||
void virtio_user_dev_uninit(struct virtio_user_dev *dev);
|
||||
void virtio_user_handle_cq(struct virtio_user_dev *dev, uint16_t queue_idx);
|
||||
+void virtio_user_handle_cq_packed(struct virtio_user_dev *dev,
|
||||
+ uint16_t queue_idx);
|
||||
uint8_t virtio_user_handle_mq(struct virtio_user_dev *dev, uint16_t q_pairs);
|
||||
#endif
|
||||
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
|
||||
index a2911febf..dddb7dd23 100644
|
||||
--- a/drivers/net/virtio/virtio_user_ethdev.c
|
||||
+++ b/drivers/net/virtio/virtio_user_ethdev.c
|
||||
@@ -271,10 +271,44 @@ virtio_user_get_queue_num(struct virtio_hw *hw, uint16_t queue_id __rte_unused)
|
||||
return dev->queue_size;
|
||||
}
|
||||
|
||||
-static int
|
||||
-virtio_user_setup_queue(struct virtio_hw *hw, struct virtqueue *vq)
|
||||
+static void
|
||||
+virtio_user_setup_queue_packed(struct virtqueue *vq,
|
||||
+ struct virtio_user_dev *dev)
|
||||
+
|
||||
+{
|
||||
+ uint16_t queue_idx = vq->vq_queue_index;
|
||||
+ struct vring_packed *vring;
|
||||
+ uint64_t desc_addr;
|
||||
+ uint64_t avail_addr;
|
||||
+ uint64_t used_addr;
|
||||
+ uint16_t i;
|
||||
+
|
||||
+ vring = &dev->packed_vrings[queue_idx];
|
||||
+ desc_addr = (uintptr_t)vq->vq_ring_virt_mem;
|
||||
+ avail_addr = desc_addr + vq->vq_nentries *
|
||||
+ sizeof(struct vring_packed_desc);
|
||||
+ used_addr = RTE_ALIGN_CEIL(avail_addr +
|
||||
+ sizeof(struct vring_packed_desc_event),
|
||||
+ VIRTIO_PCI_VRING_ALIGN);
|
||||
+ vring->num = vq->vq_nentries;
|
||||
+ vring->desc_packed =
|
||||
+ (void *)(uintptr_t)desc_addr;
|
||||
+ vring->driver_event =
|
||||
+ (void *)(uintptr_t)avail_addr;
|
||||
+ vring->device_event =
|
||||
+ (void *)(uintptr_t)used_addr;
|
||||
+ dev->packed_queues[queue_idx].avail_wrap_counter = true;
|
||||
+ dev->packed_queues[queue_idx].used_wrap_counter = true;
|
||||
+
|
||||
+ for (i = 0; i < vring->num; i++) {
|
||||
+ vring->desc_packed[i].flags = VRING_DESC_F_USED(1) |
|
||||
+ VRING_DESC_F_AVAIL(1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+virtio_user_setup_queue_split(struct virtqueue *vq, struct virtio_user_dev *dev)
|
||||
{
|
||||
- struct virtio_user_dev *dev = virtio_user_get_dev(hw);
|
||||
uint16_t queue_idx = vq->vq_queue_index;
|
||||
uint64_t desc_addr, avail_addr, used_addr;
|
||||
|
||||
@@ -288,6 +322,17 @@ virtio_user_setup_queue(struct virtio_hw *hw, struct virtqueue *vq)
|
||||
dev->vrings[queue_idx].desc = (void *)(uintptr_t)desc_addr;
|
||||
dev->vrings[queue_idx].avail = (void *)(uintptr_t)avail_addr;
|
||||
dev->vrings[queue_idx].used = (void *)(uintptr_t)used_addr;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+virtio_user_setup_queue(struct virtio_hw *hw, struct virtqueue *vq)
|
||||
+{
|
||||
+ struct virtio_user_dev *dev = virtio_user_get_dev(hw);
|
||||
+
|
||||
+ if (vtpci_packed_queue(hw))
|
||||
+ virtio_user_setup_queue_packed(vq, dev);
|
||||
+ else
|
||||
+ virtio_user_setup_queue_split(vq, dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -317,7 +362,10 @@ virtio_user_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
|
||||
struct virtio_user_dev *dev = virtio_user_get_dev(hw);
|
||||
|
||||
if (hw->cvq && (hw->cvq->vq == vq)) {
|
||||
- virtio_user_handle_cq(dev, vq->vq_queue_index);
|
||||
+ if (vtpci_packed_queue(vq->hw))
|
||||
+ virtio_user_handle_cq_packed(dev, vq->vq_queue_index);
|
||||
+ else
|
||||
+ virtio_user_handle_cq(dev, vq->vq_queue_index);
|
||||
return;
|
||||
}
|
||||
|
||||
--
|
||||
2.21.0
|
||||
|
197
SOURCES/0016-net-virtio-fix-control-VQ.patch
Normal file
197
SOURCES/0016-net-virtio-fix-control-VQ.patch
Normal file
@ -0,0 +1,197 @@
|
||||
From c276398e43bec444eb207c3184f667b3d97361f8 Mon Sep 17 00:00:00 2001
|
||||
From: Tiwei Bie <tiwei.bie@intel.com>
|
||||
Date: Wed, 23 Jan 2019 01:01:40 +0800
|
||||
Subject: [PATCH 16/18] net/virtio: fix control VQ
|
||||
|
||||
[ upstream commit 2923b8f9c41da37d63bd196ba2f037c154a6ebd5 ]
|
||||
|
||||
This patch mainly fixed below issues in the packed ring based
|
||||
control vq support in virtio driver:
|
||||
|
||||
1. When parsing the used descriptors, we have to track the
|
||||
number of descs that we need to skip;
|
||||
2. vq->vq_free_cnt was decreased twice for a same desc;
|
||||
|
||||
Meanwhile, make the function name consistent with other parts.
|
||||
|
||||
Fixes: ec194c2f1895 ("net/virtio: support packed queue in send command")
|
||||
Fixes: a4270ea4ff79 ("net/virtio: check head desc with correct wrap counter")
|
||||
|
||||
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
[changed parameters to virtio_rmb/_wmb()]
|
||||
(cherry picked from commit 2923b8f9c41da37d63bd196ba2f037c154a6ebd5)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_ethdev.c | 62 ++++++++++++++----------------
|
||||
drivers/net/virtio/virtqueue.h | 12 +-----
|
||||
2 files changed, 31 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
|
||||
index 7bd38a292..c12fb157e 100644
|
||||
--- a/drivers/net/virtio/virtio_ethdev.c
|
||||
+++ b/drivers/net/virtio/virtio_ethdev.c
|
||||
@@ -142,16 +142,17 @@ static const struct rte_virtio_xstats_name_off rte_virtio_txq_stat_strings[] = {
|
||||
struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS];
|
||||
|
||||
static struct virtio_pmd_ctrl *
|
||||
-virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
|
||||
- int *dlen, int pkt_num)
|
||||
+virtio_send_command_packed(struct virtnet_ctl *cvq,
|
||||
+ struct virtio_pmd_ctrl *ctrl,
|
||||
+ int *dlen, int pkt_num)
|
||||
{
|
||||
struct virtqueue *vq = cvq->vq;
|
||||
int head;
|
||||
struct vring_packed_desc *desc = vq->ring_packed.desc_packed;
|
||||
struct virtio_pmd_ctrl *result;
|
||||
- bool avail_wrap_counter, used_wrap_counter;
|
||||
- uint16_t flags;
|
||||
+ bool avail_wrap_counter;
|
||||
int sum = 0;
|
||||
+ int nb_descs = 0;
|
||||
int k;
|
||||
|
||||
/*
|
||||
@@ -162,11 +163,10 @@ virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
|
||||
*/
|
||||
head = vq->vq_avail_idx;
|
||||
avail_wrap_counter = vq->avail_wrap_counter;
|
||||
- used_wrap_counter = vq->used_wrap_counter;
|
||||
- desc[head].flags = VRING_DESC_F_NEXT;
|
||||
desc[head].addr = cvq->virtio_net_hdr_mem;
|
||||
desc[head].len = sizeof(struct virtio_net_ctrl_hdr);
|
||||
vq->vq_free_cnt--;
|
||||
+ nb_descs++;
|
||||
if (++vq->vq_avail_idx >= vq->vq_nentries) {
|
||||
vq->vq_avail_idx -= vq->vq_nentries;
|
||||
vq->avail_wrap_counter ^= 1;
|
||||
@@ -177,55 +177,51 @@ virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
|
||||
+ sizeof(struct virtio_net_ctrl_hdr)
|
||||
+ sizeof(ctrl->status) + sizeof(uint8_t) * sum;
|
||||
desc[vq->vq_avail_idx].len = dlen[k];
|
||||
- flags = VRING_DESC_F_NEXT;
|
||||
+ desc[vq->vq_avail_idx].flags = VRING_DESC_F_NEXT |
|
||||
+ VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
|
||||
+ VRING_DESC_F_USED(!vq->avail_wrap_counter);
|
||||
sum += dlen[k];
|
||||
vq->vq_free_cnt--;
|
||||
- flags |= VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
|
||||
- VRING_DESC_F_USED(!vq->avail_wrap_counter);
|
||||
- desc[vq->vq_avail_idx].flags = flags;
|
||||
- rte_smp_wmb();
|
||||
- vq->vq_free_cnt--;
|
||||
+ nb_descs++;
|
||||
if (++vq->vq_avail_idx >= vq->vq_nentries) {
|
||||
vq->vq_avail_idx -= vq->vq_nentries;
|
||||
vq->avail_wrap_counter ^= 1;
|
||||
}
|
||||
}
|
||||
|
||||
-
|
||||
desc[vq->vq_avail_idx].addr = cvq->virtio_net_hdr_mem
|
||||
+ sizeof(struct virtio_net_ctrl_hdr);
|
||||
desc[vq->vq_avail_idx].len = sizeof(ctrl->status);
|
||||
- flags = VRING_DESC_F_WRITE;
|
||||
- flags |= VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
|
||||
- VRING_DESC_F_USED(!vq->avail_wrap_counter);
|
||||
- desc[vq->vq_avail_idx].flags = flags;
|
||||
- flags = VRING_DESC_F_NEXT;
|
||||
- flags |= VRING_DESC_F_AVAIL(avail_wrap_counter) |
|
||||
- VRING_DESC_F_USED(!avail_wrap_counter);
|
||||
- desc[head].flags = flags;
|
||||
- rte_smp_wmb();
|
||||
-
|
||||
+ desc[vq->vq_avail_idx].flags = VRING_DESC_F_WRITE |
|
||||
+ VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
|
||||
+ VRING_DESC_F_USED(!vq->avail_wrap_counter);
|
||||
vq->vq_free_cnt--;
|
||||
+ nb_descs++;
|
||||
if (++vq->vq_avail_idx >= vq->vq_nentries) {
|
||||
vq->vq_avail_idx -= vq->vq_nentries;
|
||||
vq->avail_wrap_counter ^= 1;
|
||||
}
|
||||
|
||||
+ virtio_wmb();
|
||||
+ desc[head].flags = VRING_DESC_F_NEXT |
|
||||
+ VRING_DESC_F_AVAIL(avail_wrap_counter) |
|
||||
+ VRING_DESC_F_USED(!avail_wrap_counter);
|
||||
+
|
||||
+ virtio_wmb();
|
||||
virtqueue_notify(vq);
|
||||
|
||||
/* wait for used descriptors in virtqueue */
|
||||
- do {
|
||||
- rte_rmb();
|
||||
+ while (!desc_is_used(&desc[head], vq))
|
||||
usleep(100);
|
||||
- } while (!__desc_is_used(&desc[head], used_wrap_counter));
|
||||
+
|
||||
+ virtio_rmb();
|
||||
|
||||
/* now get used descriptors */
|
||||
- while (desc_is_used(&desc[vq->vq_used_cons_idx], vq)) {
|
||||
- vq->vq_free_cnt++;
|
||||
- if (++vq->vq_used_cons_idx >= vq->vq_nentries) {
|
||||
- vq->vq_used_cons_idx -= vq->vq_nentries;
|
||||
- vq->used_wrap_counter ^= 1;
|
||||
- }
|
||||
+ vq->vq_free_cnt += nb_descs;
|
||||
+ vq->vq_used_cons_idx += nb_descs;
|
||||
+ if (vq->vq_used_cons_idx >= vq->vq_nentries) {
|
||||
+ vq->vq_used_cons_idx -= vq->vq_nentries;
|
||||
+ vq->used_wrap_counter ^= 1;
|
||||
}
|
||||
|
||||
result = cvq->virtio_net_hdr_mz->addr;
|
||||
@@ -266,7 +262,7 @@ virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
|
||||
sizeof(struct virtio_pmd_ctrl));
|
||||
|
||||
if (vtpci_packed_queue(vq->hw)) {
|
||||
- result = virtio_pq_send_command(cvq, ctrl, dlen, pkt_num);
|
||||
+ result = virtio_send_command_packed(cvq, ctrl, dlen, pkt_num);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
|
||||
index 75f5782bc..9e74b7bd0 100644
|
||||
--- a/drivers/net/virtio/virtqueue.h
|
||||
+++ b/drivers/net/virtio/virtqueue.h
|
||||
@@ -256,7 +256,7 @@ struct virtio_tx_region {
|
||||
};
|
||||
|
||||
static inline int
|
||||
-__desc_is_used(struct vring_packed_desc *desc, bool wrap_counter)
|
||||
+desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
|
||||
{
|
||||
uint16_t used, avail, flags;
|
||||
|
||||
@@ -264,16 +264,9 @@ __desc_is_used(struct vring_packed_desc *desc, bool wrap_counter)
|
||||
used = !!(flags & VRING_DESC_F_USED(1));
|
||||
avail = !!(flags & VRING_DESC_F_AVAIL(1));
|
||||
|
||||
- return avail == used && used == wrap_counter;
|
||||
-}
|
||||
-
|
||||
-static inline int
|
||||
-desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
|
||||
-{
|
||||
- return __desc_is_used(desc, vq->used_wrap_counter);
|
||||
+ return avail == used && used == vq->used_wrap_counter;
|
||||
}
|
||||
|
||||
-
|
||||
static inline void
|
||||
vring_desc_init_packed(struct virtqueue *vq, int n)
|
||||
{
|
||||
@@ -329,7 +322,6 @@ virtqueue_enable_intr_packed(struct virtqueue *vq)
|
||||
{
|
||||
uint16_t *event_flags = &vq->ring_packed.driver_event->desc_event_flags;
|
||||
|
||||
-
|
||||
if (vq->event_flags_shadow == RING_EVENT_FLAGS_DISABLE) {
|
||||
virtio_wmb();
|
||||
vq->event_flags_shadow = RING_EVENT_FLAGS_ENABLE;
|
||||
--
|
||||
2.21.0
|
||||
|
146
SOURCES/0017-net-virtio-user-fix-control-VQ.patch
Normal file
146
SOURCES/0017-net-virtio-user-fix-control-VQ.patch
Normal file
@ -0,0 +1,146 @@
|
||||
From e5ee642672921b9e83aaa558067b6b685a7af0a3 Mon Sep 17 00:00:00 2001
|
||||
From: Tiwei Bie <tiwei.bie@intel.com>
|
||||
Date: Wed, 23 Jan 2019 01:01:41 +0800
|
||||
Subject: [PATCH 17/18] net/virtio-user: fix control VQ
|
||||
|
||||
[ upstream commit 45c224e73a3057bf62cb04f83fc1e97457a21ffa ]
|
||||
|
||||
This patch fixed below issues in the packed ring based control
|
||||
vq support in virtio user:
|
||||
|
||||
1. The idx_hdr should be used_idx instead of the id in the desc;
|
||||
2. We just need to write out a single used descriptor for each
|
||||
descriptor list;
|
||||
3. The avail/used bits should be initialized to 0;
|
||||
|
||||
Meanwhile, make the function name consistent with other parts.
|
||||
|
||||
Fixes: 48a4464029a7 ("net/virtio-user: support control VQ for packed")
|
||||
|
||||
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
(cherry picked from commit 45c224e73a3057bf62cb04f83fc1e97457a21ffa)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_ethdev.c | 11 ++++++
|
||||
.../net/virtio/virtio_user/virtio_user_dev.c | 37 +++++++++++--------
|
||||
drivers/net/virtio/virtio_user_ethdev.c | 7 +---
|
||||
3 files changed, 34 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
|
||||
index c12fb157e..a31129484 100644
|
||||
--- a/drivers/net/virtio/virtio_ethdev.c
|
||||
+++ b/drivers/net/virtio/virtio_ethdev.c
|
||||
@@ -224,6 +224,17 @@ virtio_send_command_packed(struct virtnet_ctl *cvq,
|
||||
vq->used_wrap_counter ^= 1;
|
||||
}
|
||||
|
||||
+ PMD_INIT_LOG(DEBUG, "vq->vq_free_cnt=%d\n"
|
||||
+ "vq->vq_avail_idx=%d\n"
|
||||
+ "vq->vq_used_cons_idx=%d\n"
|
||||
+ "vq->avail_wrap_counter=%d\n"
|
||||
+ "vq->used_wrap_counter=%d\n",
|
||||
+ vq->vq_free_cnt,
|
||||
+ vq->vq_avail_idx,
|
||||
+ vq->vq_used_cons_idx,
|
||||
+ vq->avail_wrap_counter,
|
||||
+ vq->used_wrap_counter);
|
||||
+
|
||||
result = cvq->virtio_net_hdr_mz->addr;
|
||||
return result;
|
||||
}
|
||||
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
index ea5149929..d1157378d 100644
|
||||
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
|
||||
@@ -632,9 +632,9 @@ desc_is_avail(struct vring_packed_desc *desc, bool wrap_counter)
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
-virtio_user_handle_ctrl_msg_pq(struct virtio_user_dev *dev,
|
||||
- struct vring_packed *vring,
|
||||
- uint16_t idx_hdr)
|
||||
+virtio_user_handle_ctrl_msg_packed(struct virtio_user_dev *dev,
|
||||
+ struct vring_packed *vring,
|
||||
+ uint16_t idx_hdr)
|
||||
{
|
||||
struct virtio_net_ctrl_hdr *hdr;
|
||||
virtio_net_ctrl_ack status = ~0;
|
||||
@@ -671,6 +671,10 @@ virtio_user_handle_ctrl_msg_pq(struct virtio_user_dev *dev,
|
||||
*(virtio_net_ctrl_ack *)(uintptr_t)
|
||||
vring->desc_packed[idx_status].addr = status;
|
||||
|
||||
+ /* Update used descriptor */
|
||||
+ vring->desc_packed[idx_hdr].id = vring->desc_packed[idx_status].id;
|
||||
+ vring->desc_packed[idx_hdr].len = sizeof(status);
|
||||
+
|
||||
return n_descs;
|
||||
}
|
||||
|
||||
@@ -679,24 +683,25 @@ virtio_user_handle_cq_packed(struct virtio_user_dev *dev, uint16_t queue_idx)
|
||||
{
|
||||
struct virtio_user_queue *vq = &dev->packed_queues[queue_idx];
|
||||
struct vring_packed *vring = &dev->packed_vrings[queue_idx];
|
||||
- uint16_t id, n_descs;
|
||||
+ uint16_t n_descs;
|
||||
|
||||
while (desc_is_avail(&vring->desc_packed[vq->used_idx],
|
||||
vq->used_wrap_counter)) {
|
||||
- id = vring->desc_packed[vq->used_idx].id;
|
||||
|
||||
- n_descs = virtio_user_handle_ctrl_msg_pq(dev, vring, id);
|
||||
+ n_descs = virtio_user_handle_ctrl_msg_packed(dev, vring,
|
||||
+ vq->used_idx);
|
||||
|
||||
- do {
|
||||
- vring->desc_packed[vq->used_idx].flags =
|
||||
- VRING_DESC_F_AVAIL(vq->used_wrap_counter) |
|
||||
- VRING_DESC_F_USED(vq->used_wrap_counter);
|
||||
- if (++vq->used_idx >= dev->queue_size) {
|
||||
- vq->used_idx -= dev->queue_size;
|
||||
- vq->used_wrap_counter ^= 1;
|
||||
- }
|
||||
- n_descs--;
|
||||
- } while (n_descs);
|
||||
+ rte_smp_wmb();
|
||||
+ vring->desc_packed[vq->used_idx].flags =
|
||||
+ VRING_DESC_F_WRITE |
|
||||
+ VRING_DESC_F_AVAIL(vq->used_wrap_counter) |
|
||||
+ VRING_DESC_F_USED(vq->used_wrap_counter);
|
||||
+
|
||||
+ vq->used_idx += n_descs;
|
||||
+ if (vq->used_idx >= dev->queue_size) {
|
||||
+ vq->used_idx -= dev->queue_size;
|
||||
+ vq->used_wrap_counter ^= 1;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
|
||||
index c01f45cab..6423e1f61 100644
|
||||
--- a/drivers/net/virtio/virtio_user_ethdev.c
|
||||
+++ b/drivers/net/virtio/virtio_user_ethdev.c
|
||||
@@ -274,7 +274,6 @@ virtio_user_get_queue_num(struct virtio_hw *hw, uint16_t queue_id __rte_unused)
|
||||
static void
|
||||
virtio_user_setup_queue_packed(struct virtqueue *vq,
|
||||
struct virtio_user_dev *dev)
|
||||
-
|
||||
{
|
||||
uint16_t queue_idx = vq->vq_queue_index;
|
||||
struct vring_packed *vring;
|
||||
@@ -300,10 +299,8 @@ virtio_user_setup_queue_packed(struct virtqueue *vq,
|
||||
dev->packed_queues[queue_idx].avail_wrap_counter = true;
|
||||
dev->packed_queues[queue_idx].used_wrap_counter = true;
|
||||
|
||||
- for (i = 0; i < vring->num; i++) {
|
||||
- vring->desc_packed[i].flags = VRING_DESC_F_USED(1) |
|
||||
- VRING_DESC_F_AVAIL(1);
|
||||
- }
|
||||
+ for (i = 0; i < vring->num; i++)
|
||||
+ vring->desc_packed[i].flags = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,97 @@
|
||||
From f3bf9a1a9b1ad3419b436855306ad8b5d8efab2f Mon Sep 17 00:00:00 2001
|
||||
From: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
Date: Thu, 20 Dec 2018 17:47:55 +0100
|
||||
Subject: [PATCH 18/18] vhost: batch used descs chains write-back with packed
|
||||
ring
|
||||
|
||||
[ upstream commit b473ec1131ee44ee25e0536a04be65246b93f4f3 ]
|
||||
|
||||
Instead of writing back descriptors chains in order, let's
|
||||
write the first chain flags last in order to improve batching.
|
||||
|
||||
Also, move the write barrier in logging cache sync, so that it
|
||||
is done only when logging is enabled. It means there is now
|
||||
one more barrier for split ring when logging is enabled.
|
||||
|
||||
With Kernel's pktgen benchmark, ~3% performance gain is measured.
|
||||
|
||||
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Tiwei Bie <tiwei.bie@intel.com>
|
||||
(cherry picked from commit b473ec1131ee44ee25e0536a04be65246b93f4f3)
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
lib/librte_vhost/vhost.h | 7 ++-----
|
||||
lib/librte_vhost/virtio_net.c | 19 ++++++++++++++++---
|
||||
2 files changed, 18 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
|
||||
index 552b9298d..adc2fb78e 100644
|
||||
--- a/lib/librte_vhost/vhost.h
|
||||
+++ b/lib/librte_vhost/vhost.h
|
||||
@@ -456,12 +456,9 @@ vhost_log_cache_sync(struct virtio_net *dev, struct vhost_virtqueue *vq)
|
||||
!dev->log_base))
|
||||
return;
|
||||
|
||||
- log_base = (unsigned long *)(uintptr_t)dev->log_base;
|
||||
+ rte_smp_wmb();
|
||||
|
||||
- /*
|
||||
- * It is expected a write memory barrier has been issued
|
||||
- * before this function is called.
|
||||
- */
|
||||
+ log_base = (unsigned long *)(uintptr_t)dev->log_base;
|
||||
|
||||
for (i = 0; i < vq->log_cache_nb_elem; i++) {
|
||||
struct log_cache_entry *elem = vq->log_cache + i;
|
||||
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
|
||||
index 15d682c3c..ec70ef947 100644
|
||||
--- a/lib/librte_vhost/virtio_net.c
|
||||
+++ b/lib/librte_vhost/virtio_net.c
|
||||
@@ -136,6 +136,8 @@ flush_shadow_used_ring_packed(struct virtio_net *dev,
|
||||
{
|
||||
int i;
|
||||
uint16_t used_idx = vq->last_used_idx;
|
||||
+ uint16_t head_idx = vq->last_used_idx;
|
||||
+ uint16_t head_flags = 0;
|
||||
|
||||
/* Split loop in two to save memory barriers */
|
||||
for (i = 0; i < vq->shadow_used_idx; i++) {
|
||||
@@ -165,12 +167,17 @@ flush_shadow_used_ring_packed(struct virtio_net *dev,
|
||||
flags &= ~VRING_DESC_F_AVAIL;
|
||||
}
|
||||
|
||||
- vq->desc_packed[vq->last_used_idx].flags = flags;
|
||||
+ if (i > 0) {
|
||||
+ vq->desc_packed[vq->last_used_idx].flags = flags;
|
||||
|
||||
- vhost_log_cache_used_vring(dev, vq,
|
||||
+ vhost_log_cache_used_vring(dev, vq,
|
||||
vq->last_used_idx *
|
||||
sizeof(struct vring_packed_desc),
|
||||
sizeof(struct vring_packed_desc));
|
||||
+ } else {
|
||||
+ head_idx = vq->last_used_idx;
|
||||
+ head_flags = flags;
|
||||
+ }
|
||||
|
||||
vq->last_used_idx += vq->shadow_used_packed[i].count;
|
||||
if (vq->last_used_idx >= vq->size) {
|
||||
@@ -179,7 +186,13 @@ flush_shadow_used_ring_packed(struct virtio_net *dev,
|
||||
}
|
||||
}
|
||||
|
||||
- rte_smp_wmb();
|
||||
+ vq->desc_packed[head_idx].flags = head_flags;
|
||||
+
|
||||
+ vhost_log_cache_used_vring(dev, vq,
|
||||
+ head_idx *
|
||||
+ sizeof(struct vring_packed_desc),
|
||||
+ sizeof(struct vring_packed_desc));
|
||||
+
|
||||
vq->shadow_used_idx = 0;
|
||||
vhost_log_cache_sync(dev, vq);
|
||||
}
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,42 @@
|
||||
From daa23dec25e8e418cd4e921531c82b5aae39b362 Mon Sep 17 00:00:00 2001
|
||||
From: Tiwei Bie <tiwei.bie@intel.com>
|
||||
Date: Tue, 19 Mar 2019 14:43:04 +0800
|
||||
Subject: [PATCH] net/virtio: fix interrupt helper for packed ring
|
||||
|
||||
When disabling interrupt, the shadow event flags should also be
|
||||
updated accordingly. The unnecessary wmb is also dropped.
|
||||
|
||||
Fixes: e9f4feb7e622 ("net/virtio: add packed virtqueue helpers")
|
||||
Cc: stable@dpdk.org
|
||||
|
||||
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
|
||||
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtqueue.h | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
|
||||
index 9e74b7bd0..c9f1c0afa 100644
|
||||
--- a/drivers/net/virtio/virtqueue.h
|
||||
+++ b/drivers/net/virtio/virtqueue.h
|
||||
@@ -296,12 +296,13 @@ vring_desc_init_split(struct vring_desc *dp, uint16_t n)
|
||||
static inline void
|
||||
virtqueue_disable_intr_packed(struct virtqueue *vq)
|
||||
{
|
||||
- uint16_t *event_flags = &vq->ring_packed.driver_event->desc_event_flags;
|
||||
-
|
||||
- *event_flags = RING_EVENT_FLAGS_DISABLE;
|
||||
+ if (vq->event_flags_shadow != RING_EVENT_FLAGS_DISABLE) {
|
||||
+ vq->event_flags_shadow = RING_EVENT_FLAGS_DISABLE;
|
||||
+ vq->ring_packed.driver_event->desc_event_flags =
|
||||
+ vq->event_flags_shadow;
|
||||
+ }
|
||||
}
|
||||
|
||||
-
|
||||
/**
|
||||
* Tell the backend not to interrupt us.
|
||||
*/
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,30 @@
|
||||
From f2e20b51ac6432390ea545e2b6247419dfcaab40 Mon Sep 17 00:00:00 2001
|
||||
From: Jens Freimann <jfreimann@redhat.com>
|
||||
Date: Mon, 16 Sep 2019 17:26:16 +0200
|
||||
Subject: [PATCH] net/virtio: fix calculation of device_event ptr
|
||||
|
||||
Fix wrong pointer arithmetic. We only need to increment by 1 if we want
|
||||
to advance it by the size of the driver event area.
|
||||
|
||||
Signed-off-by: Jens Freimann <jfreimann@redhat.com>
|
||||
---
|
||||
drivers/net/virtio/virtio_ring.h | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/virtio/virtio_ring.h b/drivers/net/virtio/virtio_ring.h
|
||||
index 1760823c6..fdc62194e 100644
|
||||
--- a/drivers/net/virtio/virtio_ring.h
|
||||
+++ b/drivers/net/virtio/virtio_ring.h
|
||||
@@ -165,8 +165,7 @@ vring_init_packed(struct vring_packed *vr, uint8_t *p, unsigned long align,
|
||||
vr->driver_event = (struct vring_packed_desc_event *)(p +
|
||||
vr->num * sizeof(struct vring_packed_desc));
|
||||
vr->device_event = (struct vring_packed_desc_event *)
|
||||
- RTE_ALIGN_CEIL((uintptr_t)(vr->driver_event +
|
||||
- sizeof(struct vring_packed_desc_event)), align);
|
||||
+ RTE_ALIGN_CEIL((uintptr_t)(vr->driver_event + 1), align);
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.21.0
|
||||
|
@ -8,10 +8,10 @@
|
||||
#% define date 20181127
|
||||
#% define shortcommit0 %(c=%{commit0}; echo ${c:0:7})
|
||||
|
||||
%define ver 18.11
|
||||
%define ver 18.11.2
|
||||
%define rel 3
|
||||
|
||||
%define srcname dpdk
|
||||
%define srcname dpdk-stable
|
||||
|
||||
Name: dpdk
|
||||
Version: %{ver}
|
||||
@ -37,9 +37,32 @@ Source505: ppc_64-power8-linuxapp-gcc-config
|
||||
Source506: x86_64-native-linuxapp-gcc-config
|
||||
|
||||
# Patches only in dpdk package
|
||||
Patch0: 0001-bus-vmbus-fix-race-in-subchannel-creation.patch
|
||||
Patch1: 0002-net-netvsc-enable-SR-IOV.patch
|
||||
Patch2: 0003-net-netvsc-disable-multi-queue-on-older-servers.patch
|
||||
|
||||
|
||||
# Bug 1525039
|
||||
Patch10: 0001-net-virtio-allocate-vrings-on-device-NUMA-node.patch
|
||||
|
||||
# Bug 1700373
|
||||
Patch11: 0001-net-virtio-add-packed-virtqueue-defines.patch
|
||||
Patch12: 0002-net-virtio-add-packed-virtqueue-helpers.patch
|
||||
Patch13: 0003-net-virtio-vring-init-for-packed-queues.patch
|
||||
Patch14: 0004-net-virtio-dump-packed-virtqueue-data.patch
|
||||
Patch15: 0005-net-virtio-implement-Tx-path-for-packed-queues.patch
|
||||
Patch16: 0006-net-virtio-implement-Rx-path-for-packed-queues.patch
|
||||
Patch17: 0007-net-virtio-support-packed-queue-in-send-command.patch
|
||||
Patch18: 0008-net-virtio-user-add-option-to-use-packed-queues.patch
|
||||
Patch19: 0009-net-virtio-user-fail-if-cq-used-with-packed-vq.patch
|
||||
Patch20: 0010-net-virtio-enable-packed-virtqueues-by-default.patch
|
||||
Patch21: 0011-net-virtio-avoid-double-accounting-of-bytes.patch
|
||||
Patch22: 0012-net-virtio-user-fix-packed-vq-option-parsing.patch
|
||||
Patch23: 0013-net-virtio-user-fix-supported-features-list.patch
|
||||
Patch24: 0014-net-virtio-check-head-desc-with-correct-wrap-counter.patch
|
||||
Patch25: 0015-net-virtio-user-support-control-VQ-for-packed.patch
|
||||
Patch26: 0016-net-virtio-fix-control-VQ.patch
|
||||
Patch27: 0017-net-virtio-user-fix-control-VQ.patch
|
||||
Patch28: 0018-vhost-batch-used-descs-chains-write-back-with-packed.patch
|
||||
Patch29: 0019-net-virtio-fix-interrupt-helper-for-packed-ring.patch
|
||||
Patch30: 0020-net-virtio-fix-calculation-of-device_event-ptr.patch
|
||||
|
||||
Summary: Set of libraries and drivers for fast packet processing
|
||||
|
||||
@ -151,7 +174,20 @@ unset RTE_SDK RTE_INCLUDE RTE_TARGET
|
||||
# Avoid appending second -Wall to everything, it breaks upstream warning
|
||||
# disablers in makefiles. Strip expclit -march= from optflags since they
|
||||
# will only guarantee build failures, DPDK is picky with that.
|
||||
export EXTRA_CFLAGS="$(echo %{optflags} | sed -e 's:-Wall::g' -e 's:-march=[[:alnum:]]* ::g') -Wformat -fPIC"
|
||||
# Note: _hardening_ldflags has to go on the extra cflags line because dpdk is
|
||||
# astoundingly convoluted in how it processes its linker flags. Fixing it in
|
||||
# dpdk is the preferred solution, but adjusting to allow a gcc option in the
|
||||
# ldflags, even when gcc is used as the linker, requires large tree-wide changes
|
||||
touch obj.o
|
||||
gcc -### obj.o 2>&1 | awk '/.*collect2.*/ { print $0}' | sed -e 's/\S*\.res\S*//g' -e 's/-z \S*//g' -e 's/[^ ]*\.o//g' -e 's/ /\n/g' | sort -u > ./noopts.txt
|
||||
gcc -### $RPM_LD_FLAGS obj.o 2>&1 | awk '/.*collect2.*/ {print $0}' | sed -e 's/\S*\.res\S*//g' -e 's/-z \S*//g' -e 's/[^ ]*\.o//g' -e 's/ /\n/g' | sort -u > ./opts.txt
|
||||
EXTRA_RPM_LDFLAGS=$(comm -13 ./noopts.txt ./opts.txt)
|
||||
rm -f obj.o
|
||||
|
||||
export EXTRA_CFLAGS="$(echo %{optflags} | sed -e 's:-Wall::g' -e 's:-march=[[:alnum:]]* ::g') -Wformat -fPIC %{_hardening_ldflags}"
|
||||
export EXTRA_LDFLAGS=$(echo %{__global_ldflags} | sed -e's/-Wl,//g' -e's/-spec.*//')
|
||||
export HOST_EXTRA_CFLAGS="$EXTRA_CFLAGS $EXTRA_RPM_LDFLAGS"
|
||||
export EXTRA_HOST_LDFLAGS=$(echo %{__global_ldflags} | sed -e's/-spec.*//')
|
||||
|
||||
# DPDK defaults to using builder-specific compiler flags. However,
|
||||
# the config has been changed by specifying CONFIG_RTE_MACHINE=default
|
||||
@ -287,6 +323,32 @@ sed -i -e 's:-%{machine_tmpl}-:-%{machine}-:g' %{buildroot}/%{_sysconfdir}/profi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Sep 16 2019 Jens Freimann <jfreimann@redhat.com> - 18.11.2-3
|
||||
- Add fix for wrong pointer calculation to fix Covscan issue
|
||||
- https://cov01.lab.eng.brq.redhat.com/covscanhub/task/135452/log/added.html
|
||||
|
||||
* Wed Aug 14 2019 Jens Freimann <jfreimann@redhat.com> - 18.11.2-2
|
||||
- Backport "net/virtio: allocate vrings on device NUMA node" (#1700373)
|
||||
|
||||
* Thu Jun 27 2019 Timothy Redaelli <tredaelli@redhat.com> - 18.11.2-1
|
||||
- Updated to DPDK 18.11.2 (#1713704)
|
||||
|
||||
* Fri May 24 2019 Maxime Coquelin <maxime.coquelin@redhat.com> - 18.11.8
|
||||
- Backport "net/virtio: allocate vrings on device NUMA node" (#1525039)
|
||||
|
||||
* Thu May 23 2019 Timothy Redaelli <tredaelli@redhat.com> - 18.11-7
|
||||
- Really use the security cflags (copied from Fedora RPM) (#1703985)
|
||||
|
||||
* Fri May 17 2019 Maxime Coquelin <maxime.coquelin@redhat.com> - 18.11-6
|
||||
- Fix basic CI gating test (#1682308)
|
||||
- Add manual gating test (#1682308)
|
||||
|
||||
* Tue Mar 26 2019 Maxime Coquelin <maxime.coquelin@redhat.com> - 18.11-5
|
||||
- Add basic CI gating test (#1682308)
|
||||
|
||||
* Mon Feb 18 2019 Jens Freimann <jfreiman@redhat.com> - 18.11-4
|
||||
- Set correct offload flags for virtio and allow jumbo frames (#1676646)
|
||||
|
||||
* Mon Feb 18 2019 Maxime Coquelin <maxime.coquelin@redhat.com> - 18.11.3
|
||||
- Backport NETVSC pmd fixes (#1676534)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user