[dpdk-dev] [PATCH v4 0/9] support in-order feature

2018-06-30 Thread Marvin Liu
In latest virtio-spec, new feature bit VIRTIO_F_IN_ORDER was introduced.
When this feature has been negotiated, virtio driver will use
descriptors in ring order: starting from offset 0 in the table, and
wrapping around at the end of the table. Vhost devices will always use
descriptors in the same order in which they have been made available.
This can reduce virtio accesses to used ring.

Based on updated virtio-spec, this series realized IN_ORDER prototype
in virtio driver. Due to new [RT]x path added into selection, also add
two new parameters mrg_rx and in_order into virtio-user vdev parameters
list. This will allow user to configure feature bits thus can impact
[RT]x path selection.

Performance of virtio user with IN_ORDER feature:

Platform: Purely
CPU: Intel(R) Xeon(R) Platinum 8160 CPU @ 2.10GHz
DPDK baseline: 18.05
Setup: testpmd with vhost vdev + testpmd with virtio vdev

+--+--+--+-+
|Vhost->Virtio |1 Queue   |2 Queues  |4 Queues |
+--+--+--+-+
|Inorder   |12.0Mpps  |24.2Mpps  |26.0Mpps |
|Normal|12.1Mpps  |18.5Mpps  |18.9Mpps |
+--+--+--+-+

+--+--++-+
|Virtio->Vhost |1 Queue   |2 Queues|4 Queues |
+--+--++-+
|Inorder   |13.8Mpps  |10.7 ~ 15.2Mpps |11.5Mpps |
|Normal|13.3Mpps  |9.8 ~ 14Mpps|10.5Mpps |
+--+--++-+

+-+--+++
|Loopback |1 Queue   |2 Queues|4 Queues|
+-+--+++
|Inorder  |7.4Mpps   |9.1 ~ 11.6Mpps  |10.5 ~ 11.3Mpps |
+-+--+++
|Normal   |7.5Mpps   |7.7 ~ 9.0Mpps   |7.6 ~ 7.8Mpps   |
+-+--+++

v4:
- disable simple [RT]x function for ARM
- squash doc update into relevant patches
- fix git-check-log and checkpatch errors

v3:
- refine [RT]x function selection logic
- fix in-order mergeable packets index error
- combine unsupport mask patch
- doc virtio in-order update
- fix checkpatch error

v2:
- merge to latest dpdk-net-virtio 
- not use in_direct for normal xmit packets
- update available ring for each descriptor
- clean up IN_ORDER xmit function
- unmask feature bits when disabled in_order or mgr_rxbuf
- extract common part between IN_ORDER and normal functions
- update performance result

Marvin Liu (11):
  vhost: advertise support in-order feature

Marvin Liu (9):
  vhost: advertise support in-order feature
  net/virtio: add in-order feature bit definition
  net/virtio-user: add unsupported features mask
  net/virtio-user: add mrg-rxbuf and in-order vdev parameters
  net/virtio: free in-order descriptors before device start
  net/virtio: extract common part for in-order functions
  net/virtio: support in-order Rx and Tx
  net/virtio: add in-order Rx/Tx into selection
  net/virtio: advertise support in-order feature

 doc/guides/nics/virtio.rst|  27 +-
 drivers/net/virtio/virtio_ethdev.c|  31 +-
 drivers/net/virtio/virtio_ethdev.h|   7 +
 drivers/net/virtio/virtio_pci.h   |   8 +
 drivers/net/virtio/virtio_rxtx.c  | 639 --
 .../net/virtio/virtio_user/virtio_user_dev.c  |  30 +-
 .../net/virtio/virtio_user/virtio_user_dev.h  |   4 +-
 drivers/net/virtio/virtio_user_ethdev.c   |  45 +-
 drivers/net/virtio/virtqueue.c|   8 +
 drivers/net/virtio/virtqueue.h|   2 +
 lib/librte_vhost/socket.c |   6 +
 lib/librte_vhost/vhost.h  |  10 +-
 12 files changed, 732 insertions(+), 85 deletions(-)

-- 
2.17.0



[dpdk-dev] [PATCH v4 2/9] net/virtio: add in-order feature bit definition

2018-06-30 Thread Marvin Liu
If VIRTIO_F_IN_ORDER has been negotiated, driver will use descriptors in
ring order: starting from offset 0 in the table, and wrapping around at
the end of the table. Also introduce use_inorder_[rt]x flag for
selection of IN_ORDER [RT]x handlers.

Signed-off-by: Marvin Liu 
Reviewed-by: Maxime Coquelin 

diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index a28ba8339..77f805df6 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -121,6 +121,12 @@ struct virtnet_ctl;
 #define VIRTIO_TRANSPORT_F_START 28
 #define VIRTIO_TRANSPORT_F_END   34
 
+/*
+ * Inorder feature indicates that all buffers are used by the device
+ * in the same order in which they have been made available.
+ */
+#define VIRTIO_F_IN_ORDER 35
+
 /* The Guest publishes the used index for which it expects an interrupt
  * at the end of the avail ring. Host should ignore the avail->flags field. */
 /* The Host publishes the avail index for which it expects a kick
@@ -233,6 +239,8 @@ struct virtio_hw {
uint8_t modern;
uint8_t use_simple_rx;
uint8_t use_simple_tx;
+   uint8_t use_inorder_rx;
+   uint8_t use_inorder_tx;
uint16_tport_id;
uint8_t mac_addr[ETHER_ADDR_LEN];
uint32_tnotify_off_multiplier;
-- 
2.17.0



[dpdk-dev] [PATCH v4 3/9] net/virtio-user: add unsupported features mask

2018-06-30 Thread Marvin Liu
This patch introduces unsupported features mask for virtio-user device.
For virtio-user server mode, when reconnecting virtio-user will retrieve
vhost device features as base and then unmask unsupported features.

Signed-off-by: Marvin Liu 
Reviewed-by: Maxime Coquelin 

diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c 
b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 4322527f2..e0e956888 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -384,6 +384,7 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char 
*path, int queues,
dev->queue_pairs = 1; /* mq disabled by default */
dev->queue_size = queue_size;
dev->mac_specified = 0;
+   dev->unsupported_features = 0;
parse_mac(dev, mac);
 
if (*ifname) {
@@ -419,10 +420,12 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char 
*path, int queues,
dev->device_features = VIRTIO_USER_SUPPORTED_FEATURES;
}
 
-   if (dev->mac_specified)
+   if (dev->mac_specified) {
dev->device_features |= (1ull << VIRTIO_NET_F_MAC);
-   else
+   } 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,
@@ -437,6 +440,14 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char 
*path, int queues,
dev->device_features &= ~(1ull << VIRTIO_NET_F_GUEST_ANNOUNCE);
dev->device_features &= ~(1ull << VIRTIO_NET_F_MQ);
dev->device_features &= ~(1ull << VIRTIO_NET_F_CTRL_MAC_ADDR);
+   dev->unsupported_features |= (1ull << VIRTIO_NET_F_CTRL_VQ);
+   dev->unsupported_features |= (1ull << VIRTIO_NET_F_CTRL_RX);
+   dev->unsupported_features |= (1ull << VIRTIO_NET_F_CTRL_VLAN);
+   dev->unsupported_features |=
+   (1ull << VIRTIO_NET_F_GUEST_ANNOUNCE);
+   dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
+   dev->unsupported_features |=
+   (1ull << VIRTIO_NET_F_CTRL_MAC_ADDR);
}
 
/* The backend will not report this feature, we add it explicitly */
@@ -444,6 +455,7 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char 
*path, int queues,
dev->device_features |= (1ull << VIRTIO_NET_F_STATUS);
 
dev->device_features &= VIRTIO_USER_SUPPORTED_FEATURES;
+   dev->unsupported_features |= ~VIRTIO_USER_SUPPORTED_FEATURES;
 
if (rte_mem_event_callback_register(VIRTIO_USER_MEM_EVENT_CLB_NAME,
virtio_user_mem_event_cb, dev)) {
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h 
b/drivers/net/virtio/virtio_user/virtio_user_dev.h
index d2d4cb825..c23ddfcc5 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
@@ -33,6 +33,7 @@ struct virtio_user_dev {
   * and will be sync with device
   */
uint64_tdevice_features; /* supported features by device */
+   uint64_tunsupported_features; /* unsupported features mask */
uint8_t status;
uint16_tport_id;
uint8_t mac_addr[ETHER_ADDR_LEN];
diff --git a/drivers/net/virtio/virtio_user_ethdev.c 
b/drivers/net/virtio/virtio_user_ethdev.c
index 1c102ca72..416dbdcf8 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -30,7 +30,6 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
int ret;
int flag;
int connectfd;
-   uint64_t features = dev->device_features;
struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->port_id];
 
connectfd = accept(dev->listenfd, NULL, NULL);
@@ -45,15 +44,8 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)
return -1;
}
 
-   features &= ~dev->device_features;
-   /* For following bits, vhost-user doesn't really need to know */
-   features &= ~(1ull << VIRTIO_NET_F_MAC);
-   features &= ~(1ull << VIRTIO_NET_F_CTRL_VLAN);
-   features &= ~(1ull << VIRTIO_NET_F_CTRL_MAC_ADDR);
-   features &= ~(1ull << VIRTIO_NET_F_STATUS);
-   if (features)
-   PMD_INIT_LOG(ERR, "WARNING: Some features 0x%" PRIx64 " are not 
supported by vhost-user!",
-features);
+   /* umask vhost-user unsupported features */
+   dev->device_features &= ~(dev->unsupported_features);
 
dev->features &= dev->device_features;
 
-- 
2.17.0



[dpdk-dev] [PATCH v4 1/9] vhost: advertise support in-order feature

2018-06-30 Thread Marvin Liu
If devices always use descriptors in the same order in which they have
been made available. These devices can offer the VIRTIO_F_IN_ORDER
feature. If negotiated, this knowledge allows devices to notify the use
of a batch of buffers to virtio driver by only writing used ring index.

Vhost user device has supported this feature by default. If vhost
dequeue zero is enabled, should disable VIRTIO_F_IN_ORDER as vhost can’t
assure that descriptors returned from NIC are in order.

Signed-off-by: Marvin Liu 
Reviewed-by: Maxime Coquelin 

diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index 0399c37bc..d63031747 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -853,6 +853,12 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
vsocket->supported_features = VIRTIO_NET_SUPPORTED_FEATURES;
vsocket->features   = VIRTIO_NET_SUPPORTED_FEATURES;
 
+   /* Dequeue zero copy can't assure descriptors returned in order */
+   if (vsocket->dequeue_zero_copy) {
+   vsocket->supported_features &= ~(1ULL << VIRTIO_F_IN_ORDER);
+   vsocket->features &= ~(1ULL << VIRTIO_F_IN_ORDER);
+   }
+
if (!(flags & RTE_VHOST_USER_IOMMU_SUPPORT)) {
vsocket->supported_features &= ~(1ULL << 
VIRTIO_F_IOMMU_PLATFORM);
vsocket->features &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM);
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 786a74f64..3437b996b 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -191,6 +191,13 @@ struct vhost_msg {
  #define VIRTIO_F_VERSION_1 32
 #endif
 
+/*
+ * Available and used descs are in same order
+ */
+#ifndef VIRTIO_F_IN_ORDER
+#define VIRTIO_F_IN_ORDER  35
+#endif
+
 /* Features supported by this builtin vhost-user net driver. */
 #define VIRTIO_NET_SUPPORTED_FEATURES ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | \
(1ULL << VIRTIO_F_ANY_LAYOUT) | \
@@ -214,7 +221,8 @@ struct vhost_msg {
(1ULL << VIRTIO_NET_F_GUEST_ECN) | \
(1ULL << VIRTIO_RING_F_INDIRECT_DESC) | \
(1ULL << VIRTIO_RING_F_EVENT_IDX) | \
-   (1ULL << VIRTIO_NET_F_MTU) | \
+   (1ULL << VIRTIO_NET_F_MTU)  | \
+   (1ULL << VIRTIO_F_IN_ORDER) | \
(1ULL << VIRTIO_F_IOMMU_PLATFORM))
 
 
-- 
2.17.0



[dpdk-dev] [PATCH v4 4/9] net/virtio-user: add mrg-rxbuf and in-order vdev parameters

2018-06-30 Thread Marvin Liu
Add parameters for configuring VIRTIO_NET_F_MRG_RXBUF and
VIRTIO_F_IN_ORDER feature bits. If feature is disabled, also update
corresponding unsupported feature bit.

Signed-off-by: Marvin Liu 
Reviewed-by: Maxime Coquelin 

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index a42d1bb30..46e292c4d 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -331,3 +331,13 @@ The user can specify below argument in devargs.
 driver, and works as a HW vhost backend. This argument is used to specify
 a virtio device needs to work in vDPA mode.
 (Default: 0 (disabled))
+
+#. ``mrg_rxbuf``:
+
+It is used to enable virtio device mergeable Rx buffer feature.
+(Default: 1 (enabled))
+
+#. ``in_order``:
+
+It is used to enable virtio device in-order feature.
+(Default: 1 (enabled))
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c 
b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index e0e956888..953c46055 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -375,7 +375,8 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
 
 int
 virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
-int cq, int queue_size, const char *mac, char **ifname)
+int cq, int queue_size, const char *mac, char **ifname,
+int mrg_rxbuf, int in_order)
 {
pthread_mutex_init(&dev->mutex, NULL);
snprintf(dev->path, PATH_MAX, "%s", path);
@@ -420,6 +421,16 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char 
*path, int queues,
dev->device_features = VIRTIO_USER_SUPPORTED_FEATURES;
}
 
+   if (!mrg_rxbuf) {
+   dev->device_features &= ~(1ull << VIRTIO_NET_F_MRG_RXBUF);
+   dev->unsupported_features |= (1ull << VIRTIO_NET_F_MRG_RXBUF);
+   }
+
+   if (!in_order) {
+   dev->device_features &= ~(1ull << VIRTIO_F_IN_ORDER);
+   dev->unsupported_features |= (1ull << VIRTIO_F_IN_ORDER);
+   }
+
if (dev->mac_specified) {
dev->device_features |= (1ull << VIRTIO_NET_F_MAC);
} else {
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h 
b/drivers/net/virtio/virtio_user/virtio_user_dev.h
index c23ddfcc5..d6e0e137b 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
@@ -48,7 +48,8 @@ int is_vhost_user_by_type(const char *path);
 int virtio_user_start_device(struct virtio_user_dev *dev);
 int virtio_user_stop_device(struct virtio_user_dev *dev);
 int virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
-int cq, int queue_size, const char *mac, char 
**ifname);
+int cq, int queue_size, const char *mac, char **ifname,
+int mrg_rxbuf, int in_order);
 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 416dbdcf8..1197967ad 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -358,8 +358,12 @@ static const char *valid_args[] = {
VIRTIO_USER_ARG_QUEUE_SIZE,
 #define VIRTIO_USER_ARG_INTERFACE_NAME "iface"
VIRTIO_USER_ARG_INTERFACE_NAME,
-#define VIRTIO_USER_ARG_SERVER_MODE "server"
+#define VIRTIO_USER_ARG_SERVER_MODE"server"
VIRTIO_USER_ARG_SERVER_MODE,
+#define VIRTIO_USER_ARG_MRG_RXBUF  "mrg_rxbuf"
+   VIRTIO_USER_ARG_MRG_RXBUF,
+#define VIRTIO_USER_ARG_IN_ORDER   "in_order"
+   VIRTIO_USER_ARG_IN_ORDER,
NULL
 };
 
@@ -462,6 +466,8 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev)
uint64_t cq = VIRTIO_USER_DEF_CQ_EN;
uint64_t queue_size = VIRTIO_USER_DEF_Q_SZ;
uint64_t server_mode = VIRTIO_USER_DEF_SERVER_MODE;
+   uint64_t mrg_rxbuf = 1;
+   uint64_t in_order = 1;
char *path = NULL;
char *ifname = NULL;
char *mac_addr = NULL;
@@ -561,6 +567,24 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev)
goto end;
}
 
+   if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_MRG_RXBUF) == 1) {
+   if (rte_kvargs_process(kvlist, VIRTIO_USER_ARG_MRG_RXBUF,
+  &get_integer_arg, &mrg_rxbuf) < 0) {
+   PMD_INIT_LOG(ERR, "error to parse %s",
+VIRTIO_USER_ARG_MRG_RXBUF);
+   goto end;
+   }
+   }
+
+   if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_IN_ORDER) == 1) {
+   if (rte_kvargs_process(kvlist, VIRTIO_USER_ARG_IN_ORDER,
+  

[dpdk-dev] [PATCH v4 5/9] net/virtio: free in-order descriptors before device start

2018-06-30 Thread Marvin Liu
Add new function for freeing IN_ORDER descriptors. As descriptors will
be allocated and freed sequentially when IN_ORDER feature was
negotiated. There will be no need to utilize chain for freed descriptors
management, only index update is enough.

Signed-off-by: Marvin Liu 

diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 92fab2174..0bca29855 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -47,6 +47,13 @@ virtio_dev_rx_queue_done(void *rxq, uint16_t offset)
return VIRTQUEUE_NUSED(vq) >= offset;
 }
 
+void
+vq_ring_free_inorder(struct virtqueue *vq, uint16_t desc_idx, uint16_t num)
+{
+   vq->vq_free_cnt += num;
+   vq->vq_desc_tail_idx = desc_idx & (vq->vq_nentries - 1);
+}
+
 void
 vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
 {
diff --git a/drivers/net/virtio/virtqueue.c b/drivers/net/virtio/virtqueue.c
index a7d0a9cbe..56a77cc71 100644
--- a/drivers/net/virtio/virtqueue.c
+++ b/drivers/net/virtio/virtqueue.c
@@ -74,6 +74,14 @@ virtqueue_rxvq_flush(struct virtqueue *vq)
desc_idx = used_idx;
rte_pktmbuf_free(vq->sw_ring[desc_idx]);
vq->vq_free_cnt++;
+   } else if (hw->use_inorder_rx) {
+   desc_idx = (uint16_t)uep->id;
+   dxp = &vq->vq_descx[desc_idx];
+   if (dxp->cookie != NULL) {
+   rte_pktmbuf_free(dxp->cookie);
+   dxp->cookie = NULL;
+   }
+   vq_ring_free_inorder(vq, desc_idx, 1);
} else {
desc_idx = (uint16_t)uep->id;
dxp = &vq->vq_descx[desc_idx];
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 14364f356..26518ed98 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -306,6 +306,8 @@ 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_inorder(struct virtqueue *vq, uint16_t desc_idx,
+ uint16_t num);
 
 static inline void
 vq_update_avail_idx(struct virtqueue *vq)
-- 
2.17.0



[dpdk-dev] [PATCH v4 8/9] net/virtio: add in-order Rx/Tx into selection

2018-06-30 Thread Marvin Liu
After IN_ORDER Rx/Tx paths added, need to update Rx/Tx path selection
logic.

Rx path select logic: If IN_ORDER is disabled will select normal Rx
path. If IN_ORDER is enabled, Rx offload and merge-able are disabled
will select simple Rx path. Otherwise will select IN_ORDER Rx path.

Tx path select logic: If IN_ORDER is disabled will select normal Tx
path. If IN_ORDER is enabled and merge-able is disabled will select
simple Tx path. Otherwise will select IN_ORDER Tx path.

Signed-off-by: Marvin Liu 
Reviewed-by: Maxime Coquelin 

diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index 46e292c4d..1b88cec96 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -201,7 +201,7 @@ The packet transmission flow is:
 Virtio PMD Rx/Tx Callbacks
 --
 
-Virtio driver has 3 Rx callbacks and 2 Tx callbacks.
+Virtio driver has 4 Rx callbacks and 3 Tx callbacks.
 
 Rx callbacks:
 
@@ -215,6 +215,9 @@ Rx callbacks:
Vector version without mergeable Rx buffer support, also fixes the available
ring indexes and uses vector instructions to optimize performance.
 
+#. ``virtio_recv_mergeable_pkts_inorder``:
+   In-order version with mergeable Rx buffer support.
+
 Tx callbacks:
 
 #. ``virtio_xmit_pkts``:
@@ -223,13 +226,17 @@ Tx callbacks:
 #. ``virtio_xmit_pkts_simple``:
Vector version fixes the available ring indexes to optimize performance.
 
+#. ``virtio_xmit_pkts_inorder``:
+   In-order version.
 
-By default, the non-vector callbacks are used:
+By default, the in-order callbacks are used:
 
 *   For Rx: If mergeable Rx buffers is disabled then ``virtio_recv_pkts`` is
-used; otherwise ``virtio_recv_mergeable_pkts``.
+used; If in-order is enabled then ``virtio_recv_mergeable_pkts_inirder``;
+otherwise ``virtio_recv_mergeable_pkts``.
 
-*   For Tx: ``virtio_xmit_pkts``.
+*   For Tx: If in-order is enabled then ``virtio_xmit_pkts_inorder``;
+otherwise ``virtio_xmit_pkts``.
 
 
 Vector callbacks will be used when:
@@ -242,6 +249,8 @@ Vector callbacks will be used when:
 
 *   Mergeable Rx buffers is disabled.
 
+*   In-order is enabled
+
 The corresponding callbacks are:
 
 *   For Rx: ``virtio_recv_pkts_vec``.
diff --git a/drivers/net/virtio/virtio_ethdev.c 
b/drivers/net/virtio/virtio_ethdev.c
index df50a571a..5f5b72de3 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1320,6 +1320,11 @@ set_rxtx_funcs(struct rte_eth_dev *eth_dev)
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",
@@ -1335,6 +1340,10 @@ set_rxtx_funcs(struct rte_eth_dev *eth_dev)
PMD_INIT_LOG(INFO, "virtio: using simple Tx path on port %u",
eth_dev->data->port_id);
eth_dev->tx_pkt_burst = virtio_xmit_pkts_simple;
+   } 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);
@@ -1871,8 +1880,18 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 
rte_spinlock_init(&hw->state_lock);
 
-   hw->use_simple_rx = 1;
-   hw->use_simple_tx = 1;
+   if (vtpci_with_feature(hw, VIRTIO_F_IN_ORDER)) {
+   if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
+   hw->use_inorder_rx = 1;
+   hw->use_inorder_tx = 1;
+   } else {
+   hw->use_simple_rx = 1;
+   hw->use_simple_tx = 1;
+   if (rx_offloads & (DEV_RX_OFFLOAD_UDP_CKSUM |
+DEV_RX_OFFLOAD_TCP_CKSUM))
+   hw->use_simple_rx = 0;
+   }
+   }
 
 #if defined RTE_ARCH_ARM64 || defined RTE_ARCH_ARM
if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON)) {
@@ -1880,14 +1899,6 @@ virtio_dev_configure(struct rte_eth_dev *dev)
hw->use_simple_tx = 0;
}
 #endif
-   if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF)) {
-   hw->use_simple_rx = 0;
-   hw->use_simple_tx = 0;
-   }
-
-   if (rx_offloads & (DEV_RX_OFFLOAD_UDP_CKSUM |
-

[dpdk-dev] [PATCH v4 7/9] net/virtio: support in-order Rx and Tx

2018-06-30 Thread Marvin Liu
IN_ORDER Rx function depends on merge-able feature. Descriptors
allocation and free will be done in bulk.

Virtio dequeue logic:
dequeue_burst_rx(burst mbufs)
for (each mbuf b) {
if (b need merge) {
merge remained mbufs
add merged mbuf to return mbufs list
} else {
add mbuf to return mbufs list
}
}
if (last mbuf c need merge) {
dequeue_burst_rx(required mbufs)
merge last mbuf c
}
refill_avail_ring_bulk()
update_avail_ring()
return mbufs list

IN_ORDER Tx function can support offloading features. Packets which
matched "can_push" option will be handled by simple xmit function. Those
packets can't match "can_push" will be handled by original xmit function
with in-order flag.

Virtio enqueue logic:
xmit_cleanup(used descs)
for (each xmit mbuf b) {
if (b can inorder xmit) {
add mbuf b to inorder burst list
continue
} else {
xmit inorder burst list
xmit mbuf b by original function
}
}
if (inorder burst list not empty) {
xmit inorder burst list
}
update_avail_ring()

Signed-off-by: Marvin Liu 
Reviewed-by: Maxime Coquelin 

diff --git a/drivers/net/virtio/virtio_ethdev.h 
b/drivers/net/virtio/virtio_ethdev.h
index bb40064ea..cd8070248 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -83,9 +83,15 @@ uint16_t virtio_recv_pkts(void *rx_queue, struct rte_mbuf 
**rx_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_inorder(void *rx_queue,
+   struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
+
 uint16_t virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
 
+uint16_t virtio_xmit_pkts_inorder(void *tx_queue, struct rte_mbuf **tx_pkts,
+   uint16_t nb_pkts);
+
 uint16_t virtio_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
 
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index e9b1b496e..6394071b8 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -122,6 +122,44 @@ virtqueue_dequeue_burst_rx(struct virtqueue *vq, struct 
rte_mbuf **rx_pkts,
return i;
 }
 
+static uint16_t
+virtqueue_dequeue_rx_inorder(struct virtqueue *vq,
+   struct rte_mbuf **rx_pkts,
+   uint32_t *len,
+   uint16_t num)
+{
+   struct vring_used_elem *uep;
+   struct rte_mbuf *cookie;
+   uint16_t used_idx = 0;
+   uint16_t i;
+
+   if (unlikely(num == 0))
+   return 0;
+
+   for (i = 0; i < num; i++) {
+   used_idx = vq->vq_used_cons_idx & (vq->vq_nentries - 1);
+   /* Desc idx same as used idx */
+   uep = &vq->vq_ring.used->ring[used_idx];
+   len[i] = uep->len;
+   cookie = (struct rte_mbuf *)vq->vq_descx[used_idx].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_used_cons_idx++;
+   vq->vq_descx[used_idx].cookie = NULL;
+   }
+
+   vq_ring_free_inorder(vq, used_idx, i);
+   return i;
+}
+
 #ifndef DEFAULT_TX_FREE_THRESH
 #define DEFAULT_TX_FREE_THRESH 32
 #endif
@@ -150,6 +188,83 @@ virtio_xmit_cleanup(struct virtqueue *vq, uint16_t num)
}
 }
 
+/* Cleanup from completed inorder transmits. */
+static void
+virtio_xmit_cleanup_inorder(struct virtqueue *vq, uint16_t num)
+{
+   uint16_t i, used_idx, desc_idx, last_idx;
+   int16_t free_cnt = 0;
+   struct vq_desc_extra *dxp = NULL;
+
+   if (unlikely(num == 0))
+   return;
+
+   for (i = 0; i < num; i++) {
+   struct vring_used_elem *uep;
+
+   used_idx = vq->vq_used_cons_idx & (vq->vq_nentries - 1);
+   uep = &vq->vq_ring.used->ring[used_idx];
+   desc_idx = (uint16_t)uep->id;
+
+   dxp = &vq->vq_descx[desc_idx];
+   vq->vq_used_cons_idx++;
+
+   if (dxp->cookie != NULL) {
+   rte_pktmbuf_free(dxp->cookie);
+   dxp->cookie = NULL;
+   }
+   }
+
+   last_idx = desc_idx + dxp->ndescs - 1;
+   free_cnt = last_idx - vq->vq_desc_tail_idx;
+   if (free_cnt <= 0)
+   free_cnt += vq->vq_nentries;
+
+   vq_ring_free_inorder(vq, 

[dpdk-dev] [PATCH v4 6/9] net/virtio: extract common part for in-order functions

2018-06-30 Thread Marvin Liu
IN_ORDER virtio-user Tx function support Tx checksum offloading and
TSO which also support on normal Tx function. So extracts common part
into separated function for reuse.

Signed-off-by: Marvin Liu 
Reviewed-by: Maxime Coquelin 

diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 0bca29855..e9b1b496e 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -246,6 +246,55 @@ tx_offload_enabled(struct virtio_hw *hw)
(var) = (val);  \
 } while (0)
 
+static inline void
+virtqueue_xmit_offload(struct virtio_net_hdr *hdr,
+   struct rte_mbuf *cookie,
+   int offload)
+{
+   if (offload) {
+   if (cookie->ol_flags & PKT_TX_TCP_SEG)
+   cookie->ol_flags |= PKT_TX_TCP_CKSUM;
+
+   switch (cookie->ol_flags & PKT_TX_L4_MASK) {
+   case PKT_TX_UDP_CKSUM:
+   hdr->csum_start = cookie->l2_len + cookie->l3_len;
+   hdr->csum_offset = offsetof(struct udp_hdr,
+   dgram_cksum);
+   hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+   break;
+
+   case PKT_TX_TCP_CKSUM:
+   hdr->csum_start = cookie->l2_len + cookie->l3_len;
+   hdr->csum_offset = offsetof(struct tcp_hdr, cksum);
+   hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+   break;
+
+   default:
+   ASSIGN_UNLESS_EQUAL(hdr->csum_start, 0);
+   ASSIGN_UNLESS_EQUAL(hdr->csum_offset, 0);
+   ASSIGN_UNLESS_EQUAL(hdr->flags, 0);
+   break;
+   }
+
+   /* TCP Segmentation Offload */
+   if (cookie->ol_flags & PKT_TX_TCP_SEG) {
+   virtio_tso_fix_cksum(cookie);
+   hdr->gso_type = (cookie->ol_flags & PKT_TX_IPV6) ?
+   VIRTIO_NET_HDR_GSO_TCPV6 :
+   VIRTIO_NET_HDR_GSO_TCPV4;
+   hdr->gso_size = cookie->tso_segsz;
+   hdr->hdr_len =
+   cookie->l2_len +
+   cookie->l3_len +
+   cookie->l4_len;
+   } else {
+   ASSIGN_UNLESS_EQUAL(hdr->gso_type, 0);
+   ASSIGN_UNLESS_EQUAL(hdr->gso_size, 0);
+   ASSIGN_UNLESS_EQUAL(hdr->hdr_len, 0);
+   }
+   }
+}
+
 static inline void
 virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
   uint16_t needed, int use_indirect, int can_push)
@@ -315,49 +364,7 @@ virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct 
rte_mbuf *cookie,
idx = start_dp[idx].next;
}
 
-   /* Checksum Offload / TSO */
-   if (offload) {
-   if (cookie->ol_flags & PKT_TX_TCP_SEG)
-   cookie->ol_flags |= PKT_TX_TCP_CKSUM;
-
-   switch (cookie->ol_flags & PKT_TX_L4_MASK) {
-   case PKT_TX_UDP_CKSUM:
-   hdr->csum_start = cookie->l2_len + cookie->l3_len;
-   hdr->csum_offset = offsetof(struct udp_hdr,
-   dgram_cksum);
-   hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
-   break;
-
-   case PKT_TX_TCP_CKSUM:
-   hdr->csum_start = cookie->l2_len + cookie->l3_len;
-   hdr->csum_offset = offsetof(struct tcp_hdr, cksum);
-   hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
-   break;
-
-   default:
-   ASSIGN_UNLESS_EQUAL(hdr->csum_start, 0);
-   ASSIGN_UNLESS_EQUAL(hdr->csum_offset, 0);
-   ASSIGN_UNLESS_EQUAL(hdr->flags, 0);
-   break;
-   }
-
-   /* TCP Segmentation Offload */
-   if (cookie->ol_flags & PKT_TX_TCP_SEG) {
-   virtio_tso_fix_cksum(cookie);
-   hdr->gso_type = (cookie->ol_flags & PKT_TX_IPV6) ?
-   VIRTIO_NET_HDR_GSO_TCPV6 :
-   VIRTIO_NET_HDR_GSO_TCPV4;
-   hdr->gso_size = cookie->tso_segsz;
-   hdr->hdr_len =
-   cookie->l2_len +
-   cookie->l3_len +
-   cookie->l4_len;
-   } else {
-   ASSIGN_UNLESS_EQUAL(hdr->gso_type, 0);
-   ASSIGN_UNLESS_EQUAL(hdr->gso_size, 0);
-   ASSIGN_UNLESS_EQUAL(hdr->hdr_len, 0);
-   }
-   }
+   virtqueue_xmit_offload(hdr, cookie, offload);
 
do {
st

[dpdk-dev] [PATCH v4 9/9] net/virtio: advertise support in-order feature

2018-06-30 Thread Marvin Liu
Signed-off-by: Marvin Liu 
Reviewed-by: Maxime Coquelin 

diff --git a/drivers/net/virtio/virtio_ethdev.h 
b/drivers/net/virtio/virtio_ethdev.h
index cd8070248..350e9ce73 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -36,6 +36,7 @@
 1ULL << VIRTIO_NET_F_GUEST_ANNOUNCE |  \
 1u << VIRTIO_RING_F_INDIRECT_DESC |\
 1ULL << VIRTIO_F_VERSION_1   | \
+1ULL << VIRTIO_F_IN_ORDER| \
 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 953c46055..39b2ef80a 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -371,6 +371,7 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
 1ULL << VIRTIO_NET_F_GUEST_CSUM|   \
 1ULL << VIRTIO_NET_F_GUEST_TSO4|   \
 1ULL << VIRTIO_NET_F_GUEST_TSO6|   \
+1ULL << VIRTIO_F_IN_ORDER  |   \
 1ULL << VIRTIO_F_VERSION_1)
 
 int
-- 
2.17.0



Re: [dpdk-dev] [PATCH v3 00/11] support in-order feature

2018-06-30 Thread Liu, Yong
Thanks, Maxime. I have sent v4 with checkpatch and commit log warnings fixed.

Regards,
Marvin 

> -Original Message-
> From: Maxime Coquelin [mailto:maxime.coque...@redhat.com]
> Sent: Friday, June 29, 2018 9:10 PM
> To: Liu, Yong ; Bie, Tiwei 
> Cc: Wang, Zhihong ; dev@dpdk.org
> Subject: Re: [PATCH v3 00/11] support in-order feature
> 
> Hi,
> 
> I was about to apply it, but there are quite a few checkpatch and
> git-check-log.sh issues reported.
> 
> Could you please resent with this fixed?
> Also, I think it would be  better to squash the doc patches in relevant
> ones.
> 
> Thanks,
> Maxime
> On 06/28/2018 11:52 PM, Marvin Liu wrote:
> > In latest virtio-spec, new feature bit VIRTIO_F_IN_ORDER was introduced.
> > When this feature has been negotiated, virtio driver will use
> > descriptors in ring order: starting from offset 0 in the table, and
> > wrapping around at the end of the table. Vhost devices will always use
> > descriptors in the same order in which they have been made available.
> > This can reduce virtio accesses to used ring.
> >
> > Based on updated virtio-spec, this series realized IN_ORDER prototype
> > in virtio driver. Due to new [RT]x path added into selection, also add
> > two new parameters mrg_rx and in_order into virtio-user vdev parameters
> > list. This will allow user to configure feature bits thus can impact
> > [RT]x path selection.
> >
> > Performance of virtio user with IN_ORDER feature:
> >
> >  Platform: Purely
> >  CPU: Intel(R) Xeon(R) Platinum 8160 CPU @ 2.10GHz
> >  DPDK baseline: 18.05
> >  Setup: testpmd with vhost vdev + testpmd with virtio vdev
> >
> >  +--+--+--+-+
> >  |Vhost->Virtio |1 Queue   |2 Queues  |4 Queues |
> >  +--+--+--+-+
> >  |Inorder   |12.0Mpps  |24.2Mpps  |26.0Mpps |
> >  |Normal|12.1Mpps  |18.5Mpps  |18.9Mpps |
> >  +--+--+--+-+
> >
> >  +--+--++-+
> >  |Virtio->Vhost |1 Queue   |2 Queues|4 Queues |
> >  +--+--++-+
> >  |Inorder   |13.8Mpps  |10.7 ~ 15.2Mpps |11.5Mpps |
> >  |Normal|13.3Mpps  |9.8 ~ 14Mpps|10.5Mpps |
> >  +--+--++-+
> >
> >  +-+--+++
> >  |Loopback |1 Queue   |2 Queues|4 Queues|
> >  +-+--+++
> >  |Inorder  |7.4Mpps   |9.1 ~ 11.6Mpps  |10.5 ~ 11.3Mpps |
> >  +-+--+++
> >  |Normal   |7.5Mpps   |7.7 ~ 9.0Mpps   |7.6 ~ 7.8Mpps   |
> >  +-+--+++
> >
> > v3:
> > - refine [RT]x function selection logic
> > - fix in-order mergable packets index error
> > - combine unsupport mask patch
> > - doc virtio in-order update
> > - fix checkpatch error
> >
> > v2:
> > - merge to latest dpdk-net-virtio
> > - not use in_direct for normal xmit packets
> > - update available ring for each descriptor
> > - clean up IN_ORDER xmit function
> > - unmask feature bits when disabled in_order or mgr_rxbuf
> > - extract common part between IN_ORDER and normal functions
> > - update performance result
> >
> > Marvin Liu (11):
> >vhost: advertise support in-order feature
> >net/virtio: add in-order feature bit definition
> >net/virtio-user: add unsupported features mask
> >net/virtio-user: add mrg_rxbuf and in_order vdev parameters
> >net/virtio: free in-order descriptors before device start
> >net/virtio: extract common part for in-order functions
> >net/virtio: support in-order Rx and Tx
> >net/virtio: add in-order Rx/Tx into selection
> >net/virtio: advertise support in-order feature
> >doc: add mrg_rxbuf and in_order parameters for virtio device
> >doc: add in-order funciton for virtio device
> >
> >   doc/guides/nics/virtio.rst|  27 +-
> >   drivers/net/virtio/virtio_ethdev.c|  29 +-
> >   drivers/net/virtio/virtio_ethdev.h|   7 +
> >   drivers/net/virtio/virtio_pci.h   |   8 +
> >   drivers/net/virtio/virtio_rxtx.c  | 635 --
> >   .../net/virtio/virtio_user/virtio_user_dev.c  |  26 +-
> >   .../net/virtio/virtio_user/virtio_user_dev.h  |   4 +-
> >   drivers/net/virtio/virtio_user_ethdev.c   |  45 +-
> >   drivers/net/virtio/virtqueue.c|   8 +
> >   drivers/net/virtio/virtqueue.h|   2 +
> >   lib/librte_vhost/socket.c |   6 +
> >   lib/librte_vhost/vhost.h  |  10 +-
> >   12 files changed, 723 insertions(+), 84 deletions(-)
> >