Skip to contentSkip to conversation

vhost: support inflight share memory protocol feature

PATCH Superseded JinYu 4 participants 29 messages Aug 29, 2019 – Sep 16, 2019 1 message not in the archive Arm/Amlogic Meson SoC support

v6 of 11 Superseded Latest is v11 →

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): 20190806182500.22320

JinYu

author
#1 lore raw

v6 cover vhost: support inflight share memory protocol feature

This patches introduces two new messages VHOST_USER_GET_INFLIGHT_FD and VHOST_USER_SET_INFLIGHT_FD to support transferring a shared buffer between qemu and backend for backend reconnection. Now It can both support split and packed ring. The example code show how these APIs work. The test has passed.

How to test the example:
1, Qemu need a patch.
https://patchwork.kernel.org/patch/10861411/
it also needs some manual modifications:
we should confirm that before we send get inflight we have already sent the set features but it seems Qemu didn't do like this. So we manually revise this, we can add below code in vhost_dev_get_inflight

    int r;

    r = vhost_dev_set_features(dev, dev->log_enabled);
    if (r < 0) {
        return -errno;
    }

before get_inflight_fd.
2, Guest OS version >= 5.0
3, run the example
4, run the qemu with vhost-user-blk-pci.
eg:

        -chardev socket,id=spdk_vhost_blk0,reconnect=1,path=xxxx\
        -device vhost-user-blk-pci,ring_packed=on,chardev=spdk_vhost_blk0,num-queues=1\

5, run fio in the guest
6, kill the example and run again.
7, the fio in the guest should continue run without errors.

JinYu (10):
vhost: add the inflight description
vhost: add packed ring
vhost: add the inflight structure
vhost: add two new messages to support a shared buffer
vhost: checkout and cleanup the resubmit inflight information
vhost: add the APIs to operate inflight ring
vhost: add APIs for user getting inflight ring
vhost: fix vring functions to support packed ring
vhost: add an API for judging vq format
vhost: add vhost-user-blk example which support inflight

 examples/vhost_blk/Makefile           |   67 ++
 examples/vhost_blk/blk.c              |  125 +++
 examples/vhost_blk/blk_spec.h         |   95 ++
 examples/vhost_blk/meson.build        |   20 +
 examples/vhost_blk/vhost_blk.c        | 1313 +++++++++++++++++++++++++
 examples/vhost_blk/vhost_blk.h        |  116 +++
 examples/vhost_blk/vhost_blk_compat.c |  195 ++++
 lib/librte_vhost/rte_vhost.h          |  250 ++++-
 lib/librte_vhost/vhost.c              |  396 +++++++-
 lib/librte_vhost/vhost.h              |   16 +
 lib/librte_vhost/vhost_user.c         |  439 +++++++++
 lib/librte_vhost/vhost_user.h         |   12 +-
 12 files changed, 3032 insertions(+), 12 deletions(-)
 create mode 100644 examples/vhost_blk/Makefile
 create mode 100644 examples/vhost_blk/blk.c
 create mode 100644 examples/vhost_blk/blk_spec.h
 create mode 100644 examples/vhost_blk/meson.build
 create mode 100644 examples/vhost_blk/vhost_blk.c
 create mode 100644 examples/vhost_blk/vhost_blk.h
 create mode 100644 examples/vhost_blk/vhost_blk_compat.c
Signature · 1 line
2.17.2
author
#2 lore raw

PATCH v6 1/10 vhost: add the inflight description

This patch add the inflight message description and the inflight share fd protocol feature flag.

---
v1 - specify the APIs are split-ring only
v2 - fix APIs and judge split or packed
v3 - add rte_vhost_ prefix and fix one issue
v4 - add the packed ring support
v5 - revise get_vring_base func depend on Tiwei's suggestion v6 - divide patch into small patches

---
 lib/librte_vhost/rte_vhost.h  | 4 ++++
 lib/librte_vhost/vhost_user.h | 8 ++++++++
 2 files changed, 12 insertions(+)
lib/librte_vhost/rte_vhost.h +4 -0
index 0226b3eff..9943575ce 100644
@@ -71,6 +71,10 @@ extern "C" {
 #define VHOST_USER_PROTOCOL_F_HOST_NOTIFIER 11
 #endif
 
+#ifndef VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD
+#define VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD 12
+#endif
+
 /** Indicate whether protocol features negotiation is supported. */
 #ifndef VHOST_USER_F_PROTOCOL_FEATURES
 #define VHOST_USER_F_PROTOCOL_FEATURES	30
lib/librte_vhost/vhost_user.h +8 -0
index 2a650fe4b..17a1d7bca 100644
@@ -112,6 +112,13 @@ typedef struct VhostUserVringArea {
 	uint64_t offset;
 } VhostUserVringArea;
 
+typedef struct VhostUserInflight {
+	uint64_t mmap_size;
+	uint64_t mmap_offset;
+	uint16_t num_queues;
+	uint16_t queue_size;
+} VhostUserInflight;
+
 typedef struct VhostUserMsg {
 	union {
 		uint32_t master; /* a VhostUserRequest value */
@@ -134,6 +141,7 @@ typedef struct VhostUserMsg {
 		struct vhost_iotlb_msg iotlb;
 		VhostUserCryptoSessionParam crypto_session;
 		VhostUserVringArea area;
+		VhostUserInflight inflight;
 	} payload;
 	int fds[VHOST_MEMORY_MAX_NREGIONS];
 	int fd_num;
Signature · 1 line
2.17.2
Reviewed-by on v6 1/10
#3 lore raw

Re: [dpdk-dev] [PATCH v6 01/10] vhost: add the inflight description

Quoted 14 lines · JinYu

This patch add the inflight message description and the inflight share fd protocol feature flag.

---
v1 - specify the APIs are split-ring only
v2 - fix APIs and judge split or packed
v3 - add rte_vhost_ prefix and fix one issue
v4 - add the packed ring support
v5 - revise get_vring_base func depend on Tiwei's suggestion v6 - divide patch into small patches

Quoted 4 lines
---
 lib/librte_vhost/rte_vhost.h  | 4 ++++
 lib/librte_vhost/vhost_user.h | 8 ++++++++
 2 files changed, 12 insertions(+)

Thanks,
Maxime

author
#4 lore raw

PATCH v6 2/10 vhost: add packed ring

In reply to JinYu

This patch add the packed ring in the rte_vhost_vring.

---
 lib/librte_vhost/rte_vhost.h | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)
lib/librte_vhost/rte_vhost.h +12 -3
index 9943575ce..7257f0965 100644
@@ -103,9 +103,18 @@ struct rte_vhost_memory {
 };
 
 struct rte_vhost_vring {
-	struct vring_desc	*desc;
-	struct vring_avail	*avail;
-	struct vring_used	*used;
+	union {
+		struct vring_desc *desc;
+		struct vring_packed_desc *desc_packed;
+	};
+	union {
+		struct vring_avail *avail;
+		struct vring_packed_desc_event *driver_event;
+	};
+	union {
+		struct vring_used *used;
+		struct vring_packed_desc_event *device_event;
+	};
 	uint64_t		log_guest_addr;
 
 	/** Deprecated, use rte_vhost_vring_call() instead. */
Signature · 1 line
2.17.2
Reviewed-by on v6 2/10
#5 lore raw

Re: [dpdk-dev] [PATCH v6 02/10] vhost: add packed ring

Quoted 27 lines · JinYu

This patch add the packed ring in the rte_vhost_vring.

---
 lib/librte_vhost/rte_vhost.h | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)
lib/librte_vhost/rte_vhost.h +5 -3
index 9943575ce..7257f0965 100644
@@ -103,9 +103,18 @@ struct rte_vhost_memory {
 };
 
 struct rte_vhost_vring {
-	struct vring_desc	*desc;
-	struct vring_avail	*avail;
-	struct vring_used	*used;
+	union {
+		struct vring_desc *desc;
+		struct vring_packed_desc *desc_packed;
+	};
+	union {

lib/librte_vhost/rte_vhost.h struct rte_vhost_memory { · line 120

Quoted 10 lines
lib/librte_vhost/rte_vhost.h +7 -0
+		struct vring_avail *avail;
+		struct vring_packed_desc_event *driver_event;
+	};
+	union {
+		struct vring_used *used;
+		struct vring_packed_desc_event *device_event;
+	};
 	uint64_t		log_guest_addr;
 
 	/** Deprecated, use rte_vhost_vring_call() instead. */

My understanding is that it does neither break the API nor ABI.

Thanks,
Maxime

author
#6 lore raw

PATCH v6 3/10 vhost: add the inflight structure

In reply to JinYu

This patch adds the inflight queue region structure include the split and packed.

---
 lib/librte_vhost/rte_vhost.h | 43 ++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
lib/librte_vhost/rte_vhost.h +43 -0
index 7257f0965..1d6b7a1cf 100644
@@ -102,6 +102,49 @@ struct rte_vhost_memory {
 	struct rte_vhost_mem_region regions[];
 };
 
+struct inflight_desc_split {
+	uint8_t inflight;
+	uint8_t padding[5];
+	uint16_t next;
+	uint64_t counter;
+};
+
+struct inflight_info_split {
+	uint64_t features;
+	uint16_t version;
+	uint16_t desc_num;
+	uint16_t last_inflight_io;
+	uint16_t used_idx;
+	struct inflight_desc_split desc[0];
+};
+
+struct inflight_desc_packed {
+	uint8_t inflight;
+	uint8_t padding;
+	uint16_t next;
+	uint16_t last;
+	uint16_t num;
+	uint64_t counter;
+	uint16_t id;
+	uint16_t flags;
+	uint32_t len;
+	uint64_t addr;
+	};
+
+struct inflight_info_packed {
+	uint64_t features;
+	uint16_t version;
+	uint16_t desc_num;
+	uint16_t free_head;
+	uint16_t old_free_head;
+	uint16_t used_idx;
+	uint16_t old_used_idx;
+	uint8_t used_wrap_counter;
+	uint8_t old_used_wrap_counter;
+	uint8_t padding[7];
+	struct inflight_desc_packed desc[0];
+};
+
 struct rte_vhost_vring {
 	union {
 		struct vring_desc *desc;
Signature · 1 line
2.17.2
#7 lore raw

Re: [dpdk-dev] [PATCH v6 03/10] vhost: add the inflight structure

Quoted 16 lines · JinYu

This patch adds the inflight queue region structure include the split and packed.

---
 lib/librte_vhost/rte_vhost.h | 43 ++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
lib/librte_vhost/rte_vhost.h +0 -0
index 7257f0965..1d6b7a1cf 100644

lib/librte_vhost/rte_vhost.h struct rte_vhost_memory { · line 105

Quoted 4 lines
lib/librte_vhost/rte_vhost.h +1 -0
@@ -102,6 +102,49 @@ struct rte_vhost_memory {
 	struct rte_vhost_mem_region regions[];
 };
 
+struct inflight_desc_split {

the struct names should be prefixed with rte_
as it is part of the API.

Quoted 46 lines
lib/librte_vhost/rte_vhost.h +42 -0
+	uint8_t inflight;
+	uint8_t padding[5];
+	uint16_t next;
+	uint64_t counter;
+};
+
+struct inflight_info_split {
+	uint64_t features;
+	uint16_t version;
+	uint16_t desc_num;
+	uint16_t last_inflight_io;
+	uint16_t used_idx;
+	struct inflight_desc_split desc[0];
+};
+
+struct inflight_desc_packed {
+	uint8_t inflight;
+	uint8_t padding;
+	uint16_t next;
+	uint16_t last;
+	uint16_t num;
+	uint64_t counter;
+	uint16_t id;
+	uint16_t flags;
+	uint32_t len;
+	uint64_t addr;
+	};
+
+struct inflight_info_packed {
+	uint64_t features;
+	uint16_t version;
+	uint16_t desc_num;
+	uint16_t free_head;
+	uint16_t old_free_head;
+	uint16_t used_idx;
+	uint16_t old_used_idx;
+	uint8_t used_wrap_counter;
+	uint8_t old_used_wrap_counter;
+	uint8_t padding[7];
+	struct inflight_desc_packed desc[0];
+};
+
 struct rte_vhost_vring {
 	union {
 		struct vring_desc *desc;
author
#8 lore raw

Re: [dpdk-dev] [PATCH v6 03/10] vhost: add the inflight structure

Quoted 32 lines

-----Original Message-----
From: Maxime Coquelin [mailto:[email protected]]
Sent: Saturday, September 7, 2019 12:46 AM
To: Yu, Jin <[email protected]>; [email protected]
Cc: Liu, Changpeng <[email protected]>; Bie, Tiwei <[email protected]>; Wang, Zhihong <[email protected]>; Lin Li <[email protected]>; Xun Ni <[email protected]>; Yu Zhang <[email protected]>
Subject: Re: [PATCH v6 03/10] vhost: add the inflight structure

Quoted 19 lines · JinYu

This patch adds the inflight queue region structure include the split and packed.

---
 lib/librte_vhost/rte_vhost.h | 43
++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
(quoted diff) +0 -0

b/lib/librte_vhost/rte_vhost.h index 7257f0965..1d6b7a1cf 100644

lib/librte_vhost/rte_vhost.h +0 -0
@@ -102,6 +102,49 @@ struct rte_vhost_memory {
 	struct rte_vhost_mem_region regions[];  };
 
Quoted 3 lines

lib/librte_vhost/rte_vhost.h struct rte_vhost_memory { · line 105

Quoted 1 line
lib/librte_vhost/rte_vhost.h +1 -0
+struct inflight_desc_split {

the struct names should be prefixed with rte_ as it is part of the API.

Got it.

Quoted 46 lines
Quoted 46 lines
lib/librte_vhost/rte_vhost.h +41 -0
+	uint8_t inflight;
+	uint8_t padding[5];
+	uint16_t next;
+	uint64_t counter;
+};
+
+struct inflight_info_split {
+	uint64_t features;
+	uint16_t version;
+	uint16_t desc_num;
+	uint16_t last_inflight_io;
+	uint16_t used_idx;
+	struct inflight_desc_split desc[0];
+};
+
+struct inflight_desc_packed {
+	uint8_t inflight;
+	uint8_t padding;
+	uint16_t next;
+	uint16_t last;
+	uint16_t num;
+	uint64_t counter;
+	uint16_t id;
+	uint16_t flags;
+	uint32_t len;
+	uint64_t addr;
+	};
+
+struct inflight_info_packed {
+	uint64_t features;
+	uint16_t version;
+	uint16_t desc_num;
+	uint16_t free_head;
+	uint16_t old_free_head;
+	uint16_t used_idx;
+	uint16_t old_used_idx;
+	uint8_t used_wrap_counter;
+	uint8_t old_used_wrap_counter;
+	uint8_t padding[7];
+	struct inflight_desc_packed desc[0]; };
+
 struct rte_vhost_vring {
 	union {
 		struct vring_desc *desc;
 
author
#9 lore raw

PATCH v6 4/10 vhost: add two new messages to support a shared buffer

In reply to JinYu

This patch introduces two new messages VHOST_USER_GET_INFLIGHT_FD and VHOST_USER_SET_INFLIGHT_FD to support transferring a shared buffer between qemu and backend.

---
 lib/librte_vhost/vhost.h      |   7 +
 lib/librte_vhost/vhost_user.c | 242 ++++++++++++++++++++++++++++++++++
 lib/librte_vhost/vhost_user.h |   4 +-
 3 files changed, 252 insertions(+), 1 deletion(-)
lib/librte_vhost/vhost.h +7 -0
index 884befa85..39f645b97 100644
@@ -286,6 +286,12 @@ struct guest_page {
 	uint64_t size;
 };
 
+struct inflight_mem_info {
+	int		fd;
+	void		*addr;
+	uint64_t	size;
+};
+
 /**
  * Device structure contains all configuration information relating
  * to the device.
@@ -303,6 +309,7 @@ struct virtio_net {
 	uint32_t		nr_vring;
 	int			dequeue_zero_copy;
 	struct vhost_virtqueue	*virtqueue[VHOST_MAX_QUEUE_PAIRS * 2];
+	struct inflight_mem_info inflight_info;
 #define IF_NAME_SZ (PATH_MAX > IFNAMSIZ ? PATH_MAX : IFNAMSIZ)
 	char			ifname[IF_NAME_SZ];
 	uint64_t		log_size;
lib/librte_vhost/vhost_user.c +242 -0

272 lines not on this page · raw message

lib/librte_vhost/vhost_user.h +3 -1
index 17a1d7bca..6563f7315 100644
@@ -54,7 +54,9 @@ typedef enum VhostUserRequest {
 	VHOST_USER_POSTCOPY_ADVISE = 28,
 	VHOST_USER_POSTCOPY_LISTEN = 29,
 	VHOST_USER_POSTCOPY_END = 30,
-	VHOST_USER_MAX = 31
+	VHOST_USER_GET_INFLIGHT_FD = 31,
+	VHOST_USER_SET_INFLIGHT_FD = 32,
+	VHOST_USER_MAX = 33
 } VhostUserRequest;
 
 typedef enum VhostUserSlaveRequest {
Signature · 1 line
2.17.2
#10 lore raw

Re: [dpdk-dev] [PATCH v6 04/10] vhost: add two new messages to support a shared buffer

Quoted 32 lines · JinYu

This patch introduces two new messages VHOST_USER_GET_INFLIGHT_FD and VHOST_USER_SET_INFLIGHT_FD to support transferring a shared buffer between qemu and backend.

---
 lib/librte_vhost/vhost.h      |   7 +
 lib/librte_vhost/vhost_user.c | 242 ++++++++++++++++++++++++++++++++++
 lib/librte_vhost/vhost_user.h |   4 +-
 3 files changed, 252 insertions(+), 1 deletion(-)
lib/librte_vhost/vhost.h +6 -0
index 884befa85..39f645b97 100644
@@ -286,6 +286,12 @@ struct guest_page {
 	uint64_t size;
 };
 
+struct inflight_mem_info {
+	int		fd;
+	void		*addr;
+	uint64_t	size;
+};
+
 /**
  * Device structure contains all configuration information relating
  * to the device.

lib/librte_vhost/vhost.h struct virtio_net { · line 312

Quoted 4 lines
lib/librte_vhost/vhost.h +1 -0
@@ -303,6 +309,7 @@ struct virtio_net {
 	uint32_t		nr_vring;
 	int			dequeue_zero_copy;
 	struct vhost_virtqueue	*virtqueue[VHOST_MAX_QUEUE_PAIRS * 2];
+	struct inflight_mem_info inflight_info;

Could it be a pointer and allocated only if the feature has been negotiated?

Quoted 52 lines
lib/librte_vhost/vhost.h +0 -0
 #define IF_NAME_SZ (PATH_MAX > IFNAMSIZ ? PATH_MAX : IFNAMSIZ)
 	char			ifname[IF_NAME_SZ];
 	uint64_t		log_size;
lib/librte_vhost/vhost_user.c +21 -0
index c9e29ece8..647929234 100644
@@ -49,6 +49,15 @@
 #define VIRTIO_MIN_MTU 68
 #define VIRTIO_MAX_MTU 65535
 
+#define INFLIGHT_ALIGNMENT	64
+#define INFLIGHT_VERSION	0xabcd
+#define VIRTQUEUE_MAX_SIZE	1024
+
+#define CLOEXEC		0x0001U
+
+#define ALIGN_DOWN(n, m) ((n) / (m) * (m))
+#define ALIGN_UP(n, m) ALIGN_DOWN((n) + (m) - 1, (m))
+
 static const char *vhost_message_str[VHOST_USER_MAX] = {
 	[VHOST_USER_NONE] = "VHOST_USER_NONE",
 	[VHOST_USER_GET_FEATURES] = "VHOST_USER_GET_FEATURES",
@@ -78,6 +87,8 @@ static const char *vhost_message_str[VHOST_USER_MAX] = {
 	[VHOST_USER_POSTCOPY_ADVISE]  = "VHOST_USER_POSTCOPY_ADVISE",
 	[VHOST_USER_POSTCOPY_LISTEN]  = "VHOST_USER_POSTCOPY_LISTEN",
 	[VHOST_USER_POSTCOPY_END]  = "VHOST_USER_POSTCOPY_END",
+	[VHOST_USER_GET_INFLIGHT_FD] = "VHOST_USER_GET_INFLIGHT_FD",
+	[VHOST_USER_SET_INFLIGHT_FD] = "VHOST_USER_SET_INFLIGHT_FD",
 };
 
 static int send_vhost_reply(int sockfd, struct VhostUserMsg *msg);
@@ -160,6 +171,16 @@ vhost_backend_cleanup(struct virtio_net *dev)
 		dev->log_addr = 0;
 	}
 
+	if (dev->inflight_info.addr) {
+		munmap(dev->inflight_info.addr, dev->inflight_info.size);
+		dev->inflight_info.addr = NULL;
+	}
+
+	if (dev->inflight_info.fd > 0) {
+		close(dev->inflight_info.fd);
+		dev->inflight_info.fd = -1;
+	}
+
 	if (dev->slave_req_fd >= 0) {
 		close(dev->slave_req_fd);
 		dev->slave_req_fd = -1;
@@ -1165,6 +1186,225 @@ virtio_is_ready(struct virtio_net *dev)
 	return 1;
 }

lib/librte_vhost/vhost_user.c virtio_is_ready(struct virtio_net *dev) · line 1197

Quoted 10 lines
lib/librte_vhost/vhost_user.c +9 -0
 
+static int
+mem_create(const char *name, unsigned int flags)
+{
+#ifdef __NR_memfd_create
+	return syscall(__NR_memfd_create, name, flags);
+#else
+	return -1;
+#endif
+}

Maybe you could use memfd_create, as done in:
lib/librte_eal/linux/eal/eal_memalloc.c

author
#11 lore raw

Re: [dpdk-dev] [PATCH v6 04/10] vhost: add two new messages to support a shared buffer

Quoted 38 lines

-----Original Message-----
From: Maxime Coquelin [mailto:[email protected]]
Sent: Saturday, September 7, 2019 1:23 AM
To: Yu, Jin <[email protected]>; [email protected]
Cc: Liu, Changpeng <[email protected]>; Bie, Tiwei <[email protected]>; Wang, Zhihong <[email protected]>; Lin Li <[email protected]>; Xun Ni <[email protected]>; Yu Zhang <[email protected]>
Subject: Re: [PATCH v6 04/10] vhost: add two new messages to support a shared buffer

Quoted 1 line · JinYu

This patch introduces two new messages VHOST_USER_GET_INFLIGHT_FD

and

Quoted 10 lines

VHOST_USER_SET_INFLIGHT_FD to support transferring a shared buffer between qemu and backend.

---
 lib/librte_vhost/vhost.h      |   7 +
 lib/librte_vhost/vhost_user.c | 242

++++++++++++++++++++++++++++++++++

Quoted 11 lines
 lib/librte_vhost/vhost_user.h |   4 +-
 3 files changed, 252 insertions(+), 1 deletion(-)
lib/librte_vhost/vhost.h index renamed from lib/librte_vhost/vhost.h +0 -0

884befa85..39f645b97 100644

lib/librte_vhost/vhost.h +0 -0
@@ -286,6 +286,12 @@ struct guest_page {
 	uint64_t size;
 };
 
Quoted 16 lines
Quoted 10 lines
lib/librte_vhost/vhost.h +6 -0
+struct inflight_mem_info {
+	int		fd;
+	void		*addr;
+	uint64_t	size;
+};
+
 /**
  * Device structure contains all configuration information relating
  * to the device.

lib/librte_vhost/vhost.h struct virtio_net { · line 312

Quoted 4 lines
lib/librte_vhost/vhost.h +1 -0
@@ -303,6 +309,7 @@ struct virtio_net {
 	uint32_t		nr_vring;
 	int			dequeue_zero_copy;
 	struct vhost_virtqueue	*virtqueue[VHOST_MAX_QUEUE_PAIRS * 2];
+	struct inflight_mem_info inflight_info;

Could it be a pointer and allocated only if the feature has been negotiated?

Ok, will fix it.

Quoted 59 lines
Quoted 14 lines
lib/librte_vhost/vhost.h +0 -0
 #define IF_NAME_SZ (PATH_MAX > IFNAMSIZ ? PATH_MAX : IFNAMSIZ)
 	char			ifname[IF_NAME_SZ];
 	uint64_t		log_size;
(quoted diff) +0 -0

b/lib/librte_vhost/vhost_user.c index c9e29ece8..647929234 100644

lib/librte_vhost/vhost_user.c +2 -0
@@ -49,6 +49,15 @@
 #define VIRTIO_MIN_MTU 68
 #define VIRTIO_MAX_MTU 65535
 
+#define INFLIGHT_ALIGNMENT	64
+#define INFLIGHT_VERSION	0xabcd

lib/librte_vhost/vhost_user.c line 63

Quoted 10 lines
lib/librte_vhost/vhost_user.c +7 -0
+#define VIRTQUEUE_MAX_SIZE	1024
+
+#define CLOEXEC		0x0001U
+
+#define ALIGN_DOWN(n, m) ((n) / (m) * (m)) #define ALIGN_UP(n, m)
+ALIGN_DOWN((n) + (m) - 1, (m))
+
 static const char *vhost_message_str[VHOST_USER_MAX] = {
 	[VHOST_USER_NONE] = "VHOST_USER_NONE",
 	[VHOST_USER_GET_FEATURES] = "VHOST_USER_GET_FEATURES",

@@ -78,6

Quoted 2 lines

+87,8 @@ static const char *vhost_message_str[VHOST_USER_MAX] = {
[VHOST_USER_POSTCOPY_ADVISE] =

"VHOST_USER_POSTCOPY_ADVISE",

Quoted 1 line

[VHOST_USER_POSTCOPY_LISTEN] =

"VHOST_USER_POSTCOPY_LISTEN",

lib/librte_vhost/vhost_user.c

Quoted 2 lines
lib/librte_vhost/vhost_user.c +1 -0
 	[VHOST_USER_POSTCOPY_END]  = "VHOST_USER_POSTCOPY_END",
+	[VHOST_USER_GET_INFLIGHT_FD] =

"VHOST_USER_GET_INFLIGHT_FD",

lib/librte_vhost/vhost_user.c

Quoted 1 line
lib/librte_vhost/vhost_user.c +1 -0
+	[VHOST_USER_SET_INFLIGHT_FD] =

"VHOST_USER_SET_INFLIGHT_FD",

Quoted 24 lines

};

static int send_vhost_reply(int sockfd, struct VhostUserMsg *msg); @@
-160,6 +171,16 @@ vhost_backend_cleanup(struct virtio_net *dev)

lib/librte_vhost/vhost_user.c +10 -0
 		dev->log_addr = 0;
 	}
 
+	if (dev->inflight_info.addr) {
+		munmap(dev->inflight_info.addr, dev->inflight_info.size);
+		dev->inflight_info.addr = NULL;
+	}
+
+	if (dev->inflight_info.fd > 0) {
+		close(dev->inflight_info.fd);
+		dev->inflight_info.fd = -1;
+	}
+
 	if (dev->slave_req_fd >= 0) {
 		close(dev->slave_req_fd);
 		dev->slave_req_fd = -1;
@@ -1165,6 +1186,225 @@ virtio_is_ready(struct virtio_net *dev)
 	return 1;
 }
 
Quoted 11 lines

lib/librte_vhost/vhost_user.c virtio_is_ready(struct virtio_net *dev) · line 1197

Quoted 7 lines
lib/librte_vhost/vhost_user.c +7 -0
+static int
+mem_create(const char *name, unsigned int flags) { #ifdef
+__NR_memfd_create
+	return syscall(__NR_memfd_create, name, flags); #else
+	return -1;
+#endif
+}

Maybe you could use memfd_create, as done in:
lib/librte_eal/linux/eal/eal_memalloc.c

Ok, I will see.

author
#12 lore raw

PATCH v6 5/10 vhost: checkout and cleanup the resubmit inflight information

In reply to JinYu

This patch shows how to checkout the inflight ring and construct the resubmit information also include destroying resubmit info.

---
 lib/librte_vhost/rte_vhost.h  |  19 ++++
 lib/librte_vhost/vhost.c      |  29 ++++-
 lib/librte_vhost/vhost.h      |   9 ++
 lib/librte_vhost/vhost_user.c | 197 ++++++++++++++++++++++++++++++++++
 4 files changed, 253 insertions(+), 1 deletion(-)
lib/librte_vhost/rte_vhost.h +19 -0
index 1d6b7a1cf..e090cdfee 100644
@@ -145,6 +145,25 @@ struct inflight_info_packed {
 	struct inflight_desc_packed desc[0];
 };
 
+struct rte_vhost_resubmit_desc {
+	uint16_t index;
+	uint64_t counter;
+};
+
+struct rte_vhost_resubmit_info {
+	struct rte_vhost_resubmit_desc *resubmit_list;
+	uint16_t resubmit_num;
+};
+
+struct rte_vhost_ring_inflight {
+	union {
+		struct inflight_info_split *inflight_split;
+		struct inflight_info_packed *inflight_packed;
+	};
+
+	struct rte_vhost_resubmit_info *resubmit_inflight;
+};
+
 struct rte_vhost_vring {
 	union {
 		struct vring_desc *desc;
lib/librte_vhost/vhost.c +28 -1
index 981837b5d..660ac2a07 100644
@@ -242,6 +242,31 @@ cleanup_vq(struct vhost_virtqueue *vq, int destroy)
 		close(vq->kickfd);
 }
 
+void
+cleanup_vq_inflight(struct virtio_net *dev, struct vhost_virtqueue *vq)
+{
+	if (!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)))
+		return;
+
+	if (vq_is_packed(dev)) {
+		if (vq->inflight_packed)
+			vq->inflight_packed = NULL;
+	} else {
+		if (vq->inflight_split)
+			vq->inflight_split = NULL;
+	}
+
+	if (vq->resubmit_inflight) {
+		if (vq->resubmit_inflight->resubmit_list) {
+			free(vq->resubmit_inflight->resubmit_list);
+			vq->resubmit_inflight->resubmit_list = NULL;
+		}
+		free(vq->resubmit_inflight);
+		vq->resubmit_inflight = NULL;
+	}
+}
+
 /*
  * Unmap any memory, close any file descriptors and
  * free any memory owned by a device.
@@ -253,8 +278,10 @@ cleanup_device(struct virtio_net *dev, int destroy)
 
 	vhost_backend_cleanup(dev);
 
-	for (i = 0; i < dev->nr_vring; i++)
+	for (i = 0; i < dev->nr_vring; i++) {
 		cleanup_vq(dev->virtqueue[i], destroy);
+		cleanup_vq_inflight(dev, dev->virtqueue[i]);
+	}
 }
 
 void
lib/librte_vhost/vhost.h +9 -0
index 39f645b97..0aa8f82cd 100644
@@ -128,6 +128,14 @@ struct vhost_virtqueue {
 	/* Physical address of used ring, for logging */
 	uint64_t		log_guest_addr;
 
+	/* inflight share memory info */
+	union {
+		struct inflight_info_split *inflight_split;
+		struct inflight_info_packed *inflight_packed;
+	};
+	struct rte_vhost_resubmit_info *resubmit_inflight;
+	uint64_t		global_counter;
+
 	uint16_t		nr_zmbuf;
 	uint16_t		zmbuf_size;
 	uint16_t		last_zmbuf_idx;
@@ -474,6 +482,7 @@ void vhost_destroy_device(int);
 void vhost_destroy_device_notify(struct virtio_net *dev);
 
 void cleanup_vq(struct vhost_virtqueue *vq, int destroy);
+void cleanup_vq_inflight(struct virtio_net *dev, struct vhost_virtqueue *vq);
 void free_vq(struct virtio_net *dev, struct vhost_virtqueue *vq);
 
 int alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx);
lib/librte_vhost/vhost_user.c +197 -0

215 lines not on this page · raw message

Signature · 1 line
2.17.2
#13 lore raw

Re: [dpdk-dev] [PATCH v6 05/10] vhost: checkout and cleanup the resubmit inflight information

Quoted 14 lines · JinYu

This patch shows how to checkout the inflight ring and construct the resubmit information also include destroying resubmit info.

---
 lib/librte_vhost/rte_vhost.h  |  19 ++++
 lib/librte_vhost/vhost.c      |  29 ++++-
 lib/librte_vhost/vhost.h      |   9 ++
 lib/librte_vhost/vhost_user.c | 197 ++++++++++++++++++++++++++++++++++
 4 files changed, 253 insertions(+), 1 deletion(-)

...

Quoted 10 lines
lib/librte_vhost/vhost_user.c +10 -0
+static int
+vhost_check_queue_inflights_packed(struct virtio_net *dev,
+						 struct vhost_virtqueue *vq)
+{
+	uint16_t i = 0;
+	uint16_t resubmit_num = 0, old_used_idx, num;
+	struct rte_vhost_resubmit_info *resubmit = NULL;
+	struct inflight_info_packed *inflight_packed;
+
+	if (!(dev->protocol_features &

lib/librte_vhost/vhost_user.c static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused, · line 1558

Quoted 10 lines
lib/librte_vhost/vhost_user.c +10 -0
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)))
+		return RTE_VHOST_MSG_RESULT_OK;
+
+	if (!vq->inflight_packed->version) {
+		vq->inflight_packed->version = INFLIGHT_VERSION;
+		return RTE_VHOST_MSG_RESULT_OK;
+	}
+
+	if ((!vq->inflight_packed))
+		return RTE_VHOST_MSG_RESULT_ERR;

It needs to be checked before before being dereferenced.

Quoted 67 lines
lib/librte_vhost/vhost_user.c +67 -0
+
+	inflight_packed = vq->inflight_packed;
+	vq->resubmit_inflight = NULL;
+	vq->global_counter = 0;
+	old_used_idx = inflight_packed->old_used_idx;
+
+	if (inflight_packed->used_idx != old_used_idx) {
+		if (inflight_packed->desc[old_used_idx].inflight == 0) {
+			inflight_packed->old_used_idx =
+				inflight_packed->used_idx;
+			inflight_packed->old_used_wrap_counter =
+				inflight_packed->used_wrap_counter;
+			inflight_packed->old_free_head =
+				inflight_packed->free_head;
+		} else {
+			inflight_packed->used_idx =
+				inflight_packed->old_used_idx;
+			inflight_packed->used_wrap_counter =
+				inflight_packed->old_used_wrap_counter;
+			inflight_packed->free_head =
+				inflight_packed->old_free_head;
+		}
+	}
+
+	for (i = 0; i < inflight_packed->desc_num; i++) {
+		if (inflight_packed->desc[i].inflight == 1)
+			resubmit_num++;
+	}
+
+	if (resubmit_num) {
+		resubmit = calloc(1, sizeof(struct rte_vhost_resubmit_info));
+		if (resubmit == NULL) {
+			RTE_LOG(ERR, VHOST_CONFIG,
+			 "Failed to allocate memory for resubmit info.\n");
+			return RTE_VHOST_MSG_RESULT_ERR;
+		}
+
+		resubmit->resubmit_list = calloc(resubmit_num,
+			sizeof(struct rte_vhost_resubmit_desc));
+		if (resubmit->resubmit_list == NULL) {
+			RTE_LOG(ERR, VHOST_CONFIG,
+			 "Failed to allocate memory for resubmit desc.\n");
+			return RTE_VHOST_MSG_RESULT_ERR;
+		}
+
+		num = 0;
+		for (i = 0; i < inflight_packed->desc_num; i++) {
+			if (vq->inflight_packed->desc[i].inflight == 1) {
+				resubmit->resubmit_list[num].index = i;
+				resubmit->resubmit_list[num].counter =
+					inflight_packed->desc[i].counter;
+				num++;
+			}
+		}
+		resubmit->resubmit_num = num;
+
+		if (resubmit->resubmit_num > 1)
+			qsort(resubmit->resubmit_list, resubmit->resubmit_num,
+				sizeof(struct rte_vhost_resubmit_desc),
+				resubmit_desc_compare);
+
+		vq->global_counter = resubmit->resubmit_list[0].counter + 1;
+		vq->resubmit_inflight = resubmit;
+	}
+
+	return RTE_VHOST_MSG_RESULT_OK;
+}
author
#14 lore raw

Re: [dpdk-dev] [PATCH v6 05/10] vhost: checkout and cleanup the resubmit inflight information

Quoted 44 lines

-----Original Message-----
From: Maxime Coquelin [mailto:[email protected]]
Sent: Monday, September 9, 2019 6:21 PM
To: Yu, Jin <[email protected]>; [email protected]
Cc: Liu, Changpeng <[email protected]>; Bie, Tiwei <[email protected]>; Wang, Zhihong <[email protected]>; Lin Li <[email protected]>; Xun Ni <[email protected]>; Yu Zhang <[email protected]>
Subject: Re: [PATCH v6 05/10] vhost: checkout and cleanup the resubmit inflight information

Quoted 15 lines · JinYu

This patch shows how to checkout the inflight ring and construct the resubmit information also include destroying resubmit info.

---
 lib/librte_vhost/rte_vhost.h  |  19 ++++
 lib/librte_vhost/vhost.c      |  29 ++++-
 lib/librte_vhost/vhost.h      |   9 ++
 lib/librte_vhost/vhost_user.c | 197
++++++++++++++++++++++++++++++++++
 4 files changed, 253 insertions(+), 1 deletion(-)

...

Quoted 14 lines
lib/librte_vhost/vhost_user.c +14 -0
+static int
+vhost_check_queue_inflights_packed(struct virtio_net *dev,
+						 struct vhost_virtqueue *vq)
+{
+	uint16_t i = 0;
+	uint16_t resubmit_num = 0, old_used_idx, num;
+	struct rte_vhost_resubmit_info *resubmit = NULL;
+	struct inflight_info_packed *inflight_packed;
+
+	if (!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)))
+		return RTE_VHOST_MSG_RESULT_OK;
+
+	if (!vq->inflight_packed->version) {
Quoted 8 lines

lib/librte_vhost/vhost_user.c static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused, · line 1558

Quoted 6 lines
lib/librte_vhost/vhost_user.c +6 -0
+		vq->inflight_packed->version = INFLIGHT_VERSION;
+		return RTE_VHOST_MSG_RESULT_OK;
+	}
+
+	if ((!vq->inflight_packed))
+		return RTE_VHOST_MSG_RESULT_ERR;

It needs to be checked before before being dereferenced.

Sorry I don't understand, you means I should check the vq pointer?

Quoted 69 lines
Quoted 69 lines
lib/librte_vhost/vhost_user.c +58 -0
+
+	inflight_packed = vq->inflight_packed;
+	vq->resubmit_inflight = NULL;
+	vq->global_counter = 0;
+	old_used_idx = inflight_packed->old_used_idx;
+
+	if (inflight_packed->used_idx != old_used_idx) {
+		if (inflight_packed->desc[old_used_idx].inflight == 0) {
+			inflight_packed->old_used_idx =
+				inflight_packed->used_idx;
+			inflight_packed->old_used_wrap_counter =
+				inflight_packed->used_wrap_counter;
+			inflight_packed->old_free_head =
+				inflight_packed->free_head;
+		} else {
+			inflight_packed->used_idx =
+				inflight_packed->old_used_idx;
+			inflight_packed->used_wrap_counter =
+				inflight_packed->old_used_wrap_counter;
+			inflight_packed->free_head =
+				inflight_packed->old_free_head;
+		}
+	}
+
+	for (i = 0; i < inflight_packed->desc_num; i++) {
+		if (inflight_packed->desc[i].inflight == 1)
+			resubmit_num++;
+	}
+
+	if (resubmit_num) {
+		resubmit = calloc(1, sizeof(struct rte_vhost_resubmit_info));
+		if (resubmit == NULL) {
+			RTE_LOG(ERR, VHOST_CONFIG,
+			 "Failed to allocate memory for resubmit info.\n");
+			return RTE_VHOST_MSG_RESULT_ERR;
+		}
+
+		resubmit->resubmit_list = calloc(resubmit_num,
+			sizeof(struct rte_vhost_resubmit_desc));
+		if (resubmit->resubmit_list == NULL) {
+			RTE_LOG(ERR, VHOST_CONFIG,
+			 "Failed to allocate memory for resubmit desc.\n");
+			return RTE_VHOST_MSG_RESULT_ERR;
+		}
+
+		num = 0;
+		for (i = 0; i < inflight_packed->desc_num; i++) {
+			if (vq->inflight_packed->desc[i].inflight == 1) {
+				resubmit->resubmit_list[num].index = i;
+				resubmit->resubmit_list[num].counter =
+					inflight_packed->desc[i].counter;
+				num++;
+			}
+		}
+		resubmit->resubmit_num = num;
+
+		if (resubmit->resubmit_num > 1)
+			qsort(resubmit->resubmit_list, resubmit-

resubmit_num,

lib/librte_vhost/vhost_user.c +9 -0
+				sizeof(struct rte_vhost_resubmit_desc),
+				resubmit_desc_compare);
+
+		vq->global_counter = resubmit->resubmit_list[0].counter + 1;
+		vq->resubmit_inflight = resubmit;
+	}
+
+	return RTE_VHOST_MSG_RESULT_OK;
+}
#15 lore raw

Re: [dpdk-dev] [PATCH v6 05/10] vhost: checkout and cleanup the resubmit inflight information

Quoted 52 lines · Jin
Quoted 44 lines

-----Original Message-----
From: Maxime Coquelin [mailto:[email protected]]
Sent: Monday, September 9, 2019 6:21 PM
To: Yu, Jin <[email protected]>; [email protected]
Cc: Liu, Changpeng <[email protected]>; Bie, Tiwei <[email protected]>; Wang, Zhihong <[email protected]>; Lin Li <[email protected]>; Xun Ni <[email protected]>; Yu Zhang <[email protected]>
Subject: Re: [PATCH v6 05/10] vhost: checkout and cleanup the resubmit inflight information

Quoted 15 lines · JinYu

This patch shows how to checkout the inflight ring and construct the resubmit information also include destroying resubmit info.

---
 lib/librte_vhost/rte_vhost.h  |  19 ++++
 lib/librte_vhost/vhost.c      |  29 ++++-
 lib/librte_vhost/vhost.h      |   9 ++
 lib/librte_vhost/vhost_user.c | 197
++++++++++++++++++++++++++++++++++
 4 files changed, 253 insertions(+), 1 deletion(-)

...

Quoted 14 lines
lib/librte_vhost/vhost_user.c +14 -0
+static int
+vhost_check_queue_inflights_packed(struct virtio_net *dev,
+						 struct vhost_virtqueue *vq)
+{
+	uint16_t i = 0;
+	uint16_t resubmit_num = 0, old_used_idx, num;
+	struct rte_vhost_resubmit_info *resubmit = NULL;
+	struct inflight_info_packed *inflight_packed;
+
+	if (!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)))
+		return RTE_VHOST_MSG_RESULT_OK;
+
+	if (!vq->inflight_packed->version) {
Quoted 8 lines

lib/librte_vhost/vhost_user.c static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused, · line 1558

Quoted 6 lines
lib/librte_vhost/vhost_user.c +6 -0
+		vq->inflight_packed->version = INFLIGHT_VERSION;
+		return RTE_VHOST_MSG_RESULT_OK;
+	}
+
+	if ((!vq->inflight_packed))
+		return RTE_VHOST_MSG_RESULT_ERR;

It needs to be checked before before being dereferenced.

Quoted 1 line

Sorry I don't understand, you means I should check the vq pointer?

No, I meant vq->inflight_packed should be checked earlier, before if (!vq->inflight_packed->version) {

Quoted 69 lines
Quoted 68 lines
Quoted 68 lines
lib/librte_vhost/vhost_user.c +58 -0
+
+	inflight_packed = vq->inflight_packed;
+	vq->resubmit_inflight = NULL;
+	vq->global_counter = 0;
+	old_used_idx = inflight_packed->old_used_idx;
+
+	if (inflight_packed->used_idx != old_used_idx) {
+		if (inflight_packed->desc[old_used_idx].inflight == 0) {
+			inflight_packed->old_used_idx =
+				inflight_packed->used_idx;
+			inflight_packed->old_used_wrap_counter =
+				inflight_packed->used_wrap_counter;
+			inflight_packed->old_free_head =
+				inflight_packed->free_head;
+		} else {
+			inflight_packed->used_idx =
+				inflight_packed->old_used_idx;
+			inflight_packed->used_wrap_counter =
+				inflight_packed->old_used_wrap_counter;
+			inflight_packed->free_head =
+				inflight_packed->old_free_head;
+		}
+	}
+
+	for (i = 0; i < inflight_packed->desc_num; i++) {
+		if (inflight_packed->desc[i].inflight == 1)
+			resubmit_num++;
+	}
+
+	if (resubmit_num) {
+		resubmit = calloc(1, sizeof(struct rte_vhost_resubmit_info));
+		if (resubmit == NULL) {
+			RTE_LOG(ERR, VHOST_CONFIG,
+			 "Failed to allocate memory for resubmit info.\n");
+			return RTE_VHOST_MSG_RESULT_ERR;
+		}
+
+		resubmit->resubmit_list = calloc(resubmit_num,
+			sizeof(struct rte_vhost_resubmit_desc));
+		if (resubmit->resubmit_list == NULL) {
+			RTE_LOG(ERR, VHOST_CONFIG,
+			 "Failed to allocate memory for resubmit desc.\n");
+			return RTE_VHOST_MSG_RESULT_ERR;
+		}
+
+		num = 0;
+		for (i = 0; i < inflight_packed->desc_num; i++) {
+			if (vq->inflight_packed->desc[i].inflight == 1) {
+				resubmit->resubmit_list[num].index = i;
+				resubmit->resubmit_list[num].counter =
+					inflight_packed->desc[i].counter;
+				num++;
+			}
+		}
+		resubmit->resubmit_num = num;
+
+		if (resubmit->resubmit_num > 1)
+			qsort(resubmit->resubmit_list, resubmit-

resubmit_num,

lib/librte_vhost/vhost_user.c +9 -0
+				sizeof(struct rte_vhost_resubmit_desc),
+				resubmit_desc_compare);
+
+		vq->global_counter = resubmit->resubmit_list[0].counter + 1;
+		vq->resubmit_inflight = resubmit;
+	}
+
+	return RTE_VHOST_MSG_RESULT_OK;
+}
author
#16 lore raw

Re: [dpdk-dev] [PATCH v6 05/10] vhost: checkout and cleanup the resubmit inflight information

Quoted 66 lines

-----Original Message-----
From: Maxime Coquelin [mailto:[email protected]]
Sent: Wednesday, September 11, 2019 4:44 PM
To: Yu, Jin <[email protected]>; [email protected]
Cc: Liu, Changpeng <[email protected]>; Bie, Tiwei <[email protected]>; Wang, Zhihong <[email protected]>; Lin Li <[email protected]>; Xun Ni <[email protected]>; Yu Zhang <[email protected]>
Subject: Re: [PATCH v6 05/10] vhost: checkout and cleanup the resubmit inflight information

Quoted 52 lines · Jin
Quoted 52 lines

-----Original Message-----
From: Maxime Coquelin [mailto:[email protected]]
Sent: Monday, September 9, 2019 6:21 PM
To: Yu, Jin <[email protected]>; [email protected]
Cc: Liu, Changpeng <[email protected]>; Bie, Tiwei <[email protected]>; Wang, Zhihong <[email protected]>; Lin Li <[email protected]>; Xun Ni <[email protected]>; Yu Zhang <[email protected]>
Subject: Re: [PATCH v6 05/10] vhost: checkout and cleanup the resubmit inflight information

Quoted 15 lines · JinYu

This patch shows how to checkout the inflight ring and construct the resubmit information also include destroying resubmit info.

---
 lib/librte_vhost/rte_vhost.h  |  19 ++++
 lib/librte_vhost/vhost.c      |  29 ++++-
 lib/librte_vhost/vhost.h      |   9 ++
 lib/librte_vhost/vhost_user.c | 197
++++++++++++++++++++++++++++++++++
 4 files changed, 253 insertions(+), 1 deletion(-)

...

Quoted 10 lines
lib/librte_vhost/vhost_user.c +10 -0
+static int
+vhost_check_queue_inflights_packed(struct virtio_net *dev,
+						 struct vhost_virtqueue *vq)
+{
+	uint16_t i = 0;
+	uint16_t resubmit_num = 0, old_used_idx, num;
+	struct rte_vhost_resubmit_info *resubmit = NULL;
+	struct inflight_info_packed *inflight_packed;
+
+	if (!(dev->protocol_features &

lib/librte_vhost/vhost_user.c static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused, · line 1558

Quoted 10 lines
lib/librte_vhost/vhost_user.c +10 -0
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)))
+		return RTE_VHOST_MSG_RESULT_OK;
+
+	if (!vq->inflight_packed->version) {
+		vq->inflight_packed->version = INFLIGHT_VERSION;
+		return RTE_VHOST_MSG_RESULT_OK;
+	}
+
+	if ((!vq->inflight_packed))
+		return RTE_VHOST_MSG_RESULT_ERR;

It needs to be checked before before being dereferenced.

Quoted 4 lines
Quoted 1 line

Sorry I don't understand, you means I should check the vq pointer?

No, I meant vq->inflight_packed should be checked earlier, before if (!vq-

Quoted 1 line

inflight_packed->version) {

Yeah you are right, Thanks. Will fix it in next version.

Quoted 70 lines
Quoted 70 lines
Quoted 69 lines
Quoted 69 lines
lib/librte_vhost/vhost_user.c +58 -0
+
+	inflight_packed = vq->inflight_packed;
+	vq->resubmit_inflight = NULL;
+	vq->global_counter = 0;
+	old_used_idx = inflight_packed->old_used_idx;
+
+	if (inflight_packed->used_idx != old_used_idx) {
+		if (inflight_packed->desc[old_used_idx].inflight == 0) {
+			inflight_packed->old_used_idx =
+				inflight_packed->used_idx;
+			inflight_packed->old_used_wrap_counter =
+				inflight_packed->used_wrap_counter;
+			inflight_packed->old_free_head =
+				inflight_packed->free_head;
+		} else {
+			inflight_packed->used_idx =
+				inflight_packed->old_used_idx;
+			inflight_packed->used_wrap_counter =
+				inflight_packed->old_used_wrap_counter;
+			inflight_packed->free_head =
+				inflight_packed->old_free_head;
+		}
+	}
+
+	for (i = 0; i < inflight_packed->desc_num; i++) {
+		if (inflight_packed->desc[i].inflight == 1)
+			resubmit_num++;
+	}
+
+	if (resubmit_num) {
+		resubmit = calloc(1, sizeof(struct rte_vhost_resubmit_info));
+		if (resubmit == NULL) {
+			RTE_LOG(ERR, VHOST_CONFIG,
+			 "Failed to allocate memory for resubmit info.\n");
+			return RTE_VHOST_MSG_RESULT_ERR;
+		}
+
+		resubmit->resubmit_list = calloc(resubmit_num,
+			sizeof(struct rte_vhost_resubmit_desc));
+		if (resubmit->resubmit_list == NULL) {
+			RTE_LOG(ERR, VHOST_CONFIG,
+			 "Failed to allocate memory for resubmit desc.\n");
+			return RTE_VHOST_MSG_RESULT_ERR;
+		}
+
+		num = 0;
+		for (i = 0; i < inflight_packed->desc_num; i++) {
+			if (vq->inflight_packed->desc[i].inflight == 1) {
+				resubmit->resubmit_list[num].index = i;
+				resubmit->resubmit_list[num].counter =
+					inflight_packed->desc[i].counter;
+				num++;
+			}
+		}
+		resubmit->resubmit_num = num;
+
+		if (resubmit->resubmit_num > 1)
+			qsort(resubmit->resubmit_list, resubmit-

resubmit_num,

lib/librte_vhost/vhost_user.c +9 -0
+				sizeof(struct rte_vhost_resubmit_desc),
+				resubmit_desc_compare);
+
+		vq->global_counter = resubmit->resubmit_list[0].counter + 1;
+		vq->resubmit_inflight = resubmit;
+	}
+
+	return RTE_VHOST_MSG_RESULT_OK;
+}
author
#17 lore raw

PATCH v6 6/10 vhost: add the APIs to operate inflight ring

In reply to JinYu

This patch introduces three APIs to operate the inflight ring. Three APIs are set, set last and clear. It includes split and packed ring.

---
 lib/librte_vhost/rte_vhost.h | 116 ++++++++++++++++
 lib/librte_vhost/vhost.c     | 252 +++++++++++++++++++++++++++++++++++
 2 files changed, 368 insertions(+)
lib/librte_vhost/rte_vhost.h +116 -0
index e090cdfee..d3b6eda21 100644
@@ -693,6 +693,122 @@ int rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem);
 int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
 			      struct rte_vhost_vring *vring);
 
+/**
+ * Set split inflight descriptor.
+ *
+ * This function save descriptors that has been comsumed in available
+ * ring
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_set_inflight_desc_split(int vid, uint16_t vring_idx,
+	uint16_t idx);
+
+/**
+ * Set packed inflight descriptor and get corresponding inflight entry
+ *
+ * This function save descriptors that has been comsumed
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param head
+ *  head of descriptors
+ * @param last
+ *  last of descriptors
+ * @param inflight_entry
+ *  corresponding inflight entry
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_set_inflight_desc_packed(int vid, uint16_t vring_idx,
+	uint16_t head, uint16_t last, uint16_t *inflight_entry);
+
+/**
+ * Save the head of list that the last batch of used descriptors.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  descriptor entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_set_last_inflight_io_split(int vid,
+	uint16_t vring_idx, uint16_t idx);
+
+/**
+ * Update the inflight free_head, used_idx and used_wrap_counter.
+ *
+ * This function will update status first before updating descriptors
+ * to used
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param head
+ *  head of descriptors
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_set_last_inflight_io_packed(int vid,
+	uint16_t vring_idx, uint16_t head);
+
+/**
+ * Clear the split inflight status.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param last_used_idx
+ *  last used idx of used ring
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_clr_inflight_desc_split(int vid, uint16_t vring_idx,
+	uint16_t last_used_idx, uint16_t idx);
+
+/**
+ * Clear the packed inflight status.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param head
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_clr_inflight_desc_packed(int vid, uint16_t vring_idx,
+	uint16_t head);
+
 /**
  * Notify the guest that used descriptors have been added to the vring.  This
  * function acts as a memory barrier.
lib/librte_vhost/vhost.c +252 -0

258 lines not on this page · raw message

Signature · 1 line
2.17.2
#18 lore raw

Re: [dpdk-dev] [PATCH v6 06/10] vhost: add the APIs to operate inflight ring

Quoted 4 lines · JinYu

This patch introduces three APIs to operate the inflight ring. Three APIs are set, set last and clear. It includes split and packed ring.

Quoted 8 lines
---
 lib/librte_vhost/rte_vhost.h | 116 ++++++++++++++++
 lib/librte_vhost/vhost.c     | 252 +++++++++++++++++++++++++++++++++++
 2 files changed, 368 insertions(+)

Hi - you need to update the version map for the new APIs, or you will see the following types of message with make,

rte_vhost_set_inflight_desc_split is flagged as experimental but is not listed in version map
Please add rte_vhost_set_inflight_desc_split to the version map

#19 lore raw

Re: [dpdk-dev] [PATCH v6 06/10] vhost: add the APIs to operate inflight ring

In reply to JinYu
Quoted 211 lines · JinYu

This patch introduces three APIs to operate the inflight ring. Three APIs are set, set last and clear. It includes split and packed ring.

---
 lib/librte_vhost/rte_vhost.h | 116 ++++++++++++++++
 lib/librte_vhost/vhost.c     | 252 +++++++++++++++++++++++++++++++++++
 2 files changed, 368 insertions(+)
lib/librte_vhost/rte_vhost.h +116 -0
index e090cdfee..d3b6eda21 100644
@@ -693,6 +693,122 @@ int rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem);
 int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
 			      struct rte_vhost_vring *vring);
 
+/**
+ * Set split inflight descriptor.
+ *
+ * This function save descriptors that has been comsumed in available
+ * ring
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_set_inflight_desc_split(int vid, uint16_t vring_idx,
+	uint16_t idx);
+
+/**
+ * Set packed inflight descriptor and get corresponding inflight entry
+ *
+ * This function save descriptors that has been comsumed
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param head
+ *  head of descriptors
+ * @param last
+ *  last of descriptors
+ * @param inflight_entry
+ *  corresponding inflight entry
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_set_inflight_desc_packed(int vid, uint16_t vring_idx,
+	uint16_t head, uint16_t last, uint16_t *inflight_entry);
+
+/**
+ * Save the head of list that the last batch of used descriptors.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  descriptor entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_set_last_inflight_io_split(int vid,
+	uint16_t vring_idx, uint16_t idx);
+
+/**
+ * Update the inflight free_head, used_idx and used_wrap_counter.
+ *
+ * This function will update status first before updating descriptors
+ * to used
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param head
+ *  head of descriptors
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_set_last_inflight_io_packed(int vid,
+	uint16_t vring_idx, uint16_t head);
+
+/**
+ * Clear the split inflight status.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param last_used_idx
+ *  last used idx of used ring
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_clr_inflight_desc_split(int vid, uint16_t vring_idx,
+	uint16_t last_used_idx, uint16_t idx);
+
+/**
+ * Clear the packed inflight status.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param head
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_clr_inflight_desc_packed(int vid, uint16_t vring_idx,
+	uint16_t head);
+
 /**
  * Notify the guest that used descriptors have been added to the vring.  This
  * function acts as a memory barrier.
lib/librte_vhost/vhost.c +63 -0
index 660ac2a07..58940152f 100644
@@ -783,6 +783,258 @@ rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
 	return 0;
 }
 
+int
+rte_vhost_set_inflight_desc_split(int vid, uint16_t vring_idx,
+	uint16_t idx)
+{
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+
+	dev = get_device(vid);
+	if (unlikely(!dev))
+		return -1;
+
+	if (unlikely(!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))))
+		return 0;
+
+	if (unlikely(vq_is_packed(dev)))
+		return -1;
+
+	if (unlikely(vring_idx >= VHOST_MAX_VRING))
+		return -1;
+
+	vq = dev->virtqueue[vring_idx];
+	if (unlikely(!vq))
+		return -1;
+
+	if (unlikely(!vq->inflight_split))
+		return -1;
+
+	vq->inflight_split->desc[idx].counter = vq->global_counter++;
+	vq->inflight_split->desc[idx].inflight = 1;
+	return 0;
+}
+
+int
+rte_vhost_set_inflight_desc_packed(int vid, uint16_t vring_idx,
+	uint16_t head, uint16_t last, uint16_t *inflight_entry)
+{
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+	struct inflight_info_packed *inflight_info;
+	struct vring_packed_desc *desc;
+	uint16_t old_free_head, free_head;
+
+	dev = get_device(vid);
+	if (unlikely(!dev))
+		return -1;
+
+	if (unlikely(!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))))
+		return 0;
+
+	if (unlikely(!vq_is_packed(dev)))
+		return -1;
+
+	if (unlikely(vring_idx >= VHOST_MAX_VRING))
+		return -1;
+
+	vq = dev->virtqueue[vring_idx];
+	if (unlikely(!vq))
+		return -1;
+
+	inflight_info = vq->inflight_packed;
+	if (unlikely(!inflight_info))

lib/librte_vhost/vhost.c rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx, · line 858

Quoted 10 lines
lib/librte_vhost/vhost.c +10 -0
+		return -1;
+
+	desc = vq->desc_packed;
+	old_free_head = inflight_info->old_free_head;
+	free_head = old_free_head;
+
+	/* init header descriptor */
+	inflight_info->desc[old_free_head].num = 0;
+	inflight_info->desc[old_free_head].counter = vq->global_counter++;
+	inflight_info->desc[old_free_head].inflight = 1;

I think head has to be validated so that it does not causes out of bounds accesses.

Quoted 41 lines
lib/librte_vhost/vhost.c +41 -0
+	/* save desc entry in flight entry */
+	while (head != ((last + 1) % vq->size)) {
+		inflight_info->desc[old_free_head].num++;
+		inflight_info->desc[free_head].addr = desc[head].addr;
+		inflight_info->desc[free_head].len = desc[head].len;
+		inflight_info->desc[free_head].flags = desc[head].flags;
+		inflight_info->desc[free_head].id = desc[head].id;
+
+		inflight_info->desc[old_free_head].last = free_head;
+		free_head = inflight_info->desc[free_head].next;
+		inflight_info->free_head = free_head;
+		head = (head + 1) % vq->size;
+	}
+
+	inflight_info->old_free_head = free_head;
+	*inflight_entry = old_free_head;
+
+	return 0;
+}
+
+int
+rte_vhost_clr_inflight_desc_split(int vid, uint16_t vring_idx,
+	uint16_t last_used_idx, uint16_t idx)
+{
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+
+	dev = get_device(vid);
+	if (unlikely(!dev))
+		return -1;
+
+	if (unlikely(!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))))
+		return 0;
+
+	if (unlikely(vq_is_packed(dev)))
+		return -1;
+
+	if (unlikely(vring_idx >= VHOST_MAX_VRING))
+		return -1;
+

lib/librte_vhost/vhost.c rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx, · line 910

Quoted 10 lines
lib/librte_vhost/vhost.c +10 -0
+	vq = dev->virtqueue[vring_idx];
+	if (unlikely(!vq))
+		return -1;
+
+	if (unlikely(!vq->inflight_split))
+		return -1;
+
+	rte_compiler_barrier();
+
+	vq->inflight_split->desc[idx].inflight = 0;

Maybe it would be better to check idx value, so that it does not causes out-of-bound accesses.

Quoted 30 lines
lib/librte_vhost/vhost.c +30 -0
+
+	rte_compiler_barrier();
+
+	vq->inflight_split->used_idx = last_used_idx;
+	return 0;
+}
+
+int
+rte_vhost_clr_inflight_desc_packed(int vid, uint16_t vring_idx,
+	uint16_t head)
+{
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+	struct inflight_info_packed *inflight_info;
+
+	dev = get_device(vid);
+	if (unlikely(!dev))
+		return -1;
+
+	if (unlikely(!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))))
+		return 0;
+
+	if (unlikely(!vq_is_packed(dev)))
+		return -1;
+
+	if (unlikely(vring_idx >= VHOST_MAX_VRING))
+		return -1;
+
+	vq = dev->virtqueue[vring_idx];

lib/librte_vhost/vhost.c rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx, · line 950

Quoted 10 lines
lib/librte_vhost/vhost.c +10 -0
+	if (unlikely(!vq))
+		return -1;
+
+	inflight_info = vq->inflight_packed;
+	if (unlikely(!inflight_info))
+		return -1;
+
+	rte_compiler_barrier();
+
+	inflight_info->desc[head].inflight = 0;

Maybe it would be better to check head value, so that it does not causes out-of-bound accesses.

Quoted 63 lines
lib/librte_vhost/vhost.c +63 -0
+	rte_compiler_barrier();
+
+	inflight_info->old_free_head = inflight_info->free_head;
+	inflight_info->old_used_idx = inflight_info->used_idx;
+	inflight_info->old_used_wrap_counter = inflight_info->used_wrap_counter;
+
+	return 0;
+}
+
+int
+rte_vhost_set_last_inflight_io_split(int vid, uint16_t vring_idx,
+	uint16_t idx)
+{
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+
+	dev = get_device(vid);
+	if (unlikely(!dev))
+		return -1;
+
+	if (unlikely(!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))))
+		return 0;
+
+	if (unlikely(vq_is_packed(dev)))
+		return -1;
+
+	if (unlikely(vring_idx >= VHOST_MAX_VRING))
+		return -1;
+
+	vq = dev->virtqueue[vring_idx];
+	if (unlikely(!vq))
+		return -1;
+
+	if (unlikely(!vq->inflight_split))
+		return -1;
+
+	vq->inflight_split->last_inflight_io = idx;
+	return 0;
+}
+
+int
+rte_vhost_set_last_inflight_io_packed(int vid, uint16_t vring_idx,
+	uint16_t head)
+{
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+	struct inflight_info_packed *inflight_info;
+	uint16_t last;
+
+	dev = get_device(vid);
+	if (unlikely(!dev))
+		return -1;
+
+	if (unlikely(!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))))
+		return 0;
+
+	if (unlikely(!vq_is_packed(dev)))
+		return -1;
+
+	if (unlikely(vring_idx >= VHOST_MAX_VRING))
+		return -1;

lib/librte_vhost/vhost.c rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx, · line 1024

Quoted 10 lines
lib/librte_vhost/vhost.c +10 -0
+
+	vq = dev->virtqueue[vring_idx];
+	if (unlikely(!vq))
+		return -1;
+
+	inflight_info = vq->inflight_packed;
+	if (unlikely(!inflight_info))
+		return -1;
+
+	last = inflight_info->desc[head].last;

Ditto

Quoted 16 lines
lib/librte_vhost/vhost.c +12 -0
+	inflight_info->desc[last].next = inflight_info->free_head;
+	inflight_info->free_head = head;
+	inflight_info->used_idx += inflight_info->desc[head].num;
+	if (inflight_info->used_idx >= inflight_info->desc_num) {
+		inflight_info->used_idx -= inflight_info->desc_num;
+		inflight_info->used_wrap_counter =
+			!inflight_info->used_wrap_counter;
+	}
+
+	return 0;
+}
+
 int
 rte_vhost_vring_call(int vid, uint16_t vring_idx)
 {
author
#20 lore raw

Re: [dpdk-dev] [PATCH v6 06/10] vhost: add the APIs to operate inflight ring

Quoted 230 lines

-----Original Message-----
From: Maxime Coquelin [mailto:[email protected]]
Sent: Thursday, September 12, 2019 5:27 PM
To: Yu, Jin <[email protected]>; [email protected]
Cc: Liu, Changpeng <[email protected]>; Bie, Tiwei <[email protected]>; Wang, Zhihong <[email protected]>; Lin Li <[email protected]>; Xun Ni <[email protected]>; Yu Zhang <[email protected]>
Subject: Re: [PATCH v6 06/10] vhost: add the APIs to operate inflight ring

Quoted 17 lines · JinYu

This patch introduces three APIs to operate the inflight ring. Three APIs are set, set last and clear. It includes split and packed ring.

---
 lib/librte_vhost/rte_vhost.h | 116 ++++++++++++++++
 lib/librte_vhost/vhost.c     | 252 +++++++++++++++++++++++++++++++++++
 2 files changed, 368 insertions(+)
(quoted diff) +0 -0

b/lib/librte_vhost/rte_vhost.h index e090cdfee..d3b6eda21 100644

lib/librte_vhost/rte_vhost.h +0 -0
@@ -693,6 +693,122 @@ int rte_vhost_get_mem_table(int vid, struct
Quoted 1 line

rte_vhost_memory **mem); int rte_vhost_get_vhost_vring(int vid, uint16_t

vring_idx,

lib/librte_vhost/vhost.c rte_vhost_get_vhost_vring(int vid, uint16_t

Quoted 127 lines
lib/librte_vhost/rte_vhost.h +117 -0
 			      struct rte_vhost_vring *vring);
 
+/**
+ * Set split inflight descriptor.
+ *
+ * This function save descriptors that has been comsumed in available
+ * ring
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_set_inflight_desc_split(int vid, uint16_t vring_idx,
+	uint16_t idx);
+
+/**
+ * Set packed inflight descriptor and get corresponding inflight
+entry
+ *
+ * This function save descriptors that has been comsumed
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param head
+ *  head of descriptors
+ * @param last
+ *  last of descriptors
+ * @param inflight_entry
+ *  corresponding inflight entry
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_set_inflight_desc_packed(int vid, uint16_t vring_idx,
+	uint16_t head, uint16_t last, uint16_t *inflight_entry);
+
+/**
+ * Save the head of list that the last batch of used descriptors.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  descriptor entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_set_last_inflight_io_split(int vid,
+	uint16_t vring_idx, uint16_t idx);
+
+/**
+ * Update the inflight free_head, used_idx and used_wrap_counter.
+ *
+ * This function will update status first before updating descriptors
+ * to used
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param head
+ *  head of descriptors
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_set_last_inflight_io_packed(int vid,
+	uint16_t vring_idx, uint16_t head);
+
+/**
+ * Clear the split inflight status.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param last_used_idx
+ *  last used idx of used ring
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_clr_inflight_desc_split(int vid, uint16_t vring_idx,
+	uint16_t last_used_idx, uint16_t idx);
+
+/**
+ * Clear the packed inflight status.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param head
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_clr_inflight_desc_packed(int vid, uint16_t vring_idx,
+	uint16_t head);
+
 /**
  * Notify the guest that used descriptors have been added to the vring.  This
  * function acts as a memory barrier.
lib/librte_vhost/vhost.c index renamed from lib/librte_vhost/vhost.c +0 -0

660ac2a07..58940152f 100644

lib/librte_vhost/vhost.c +0 -0
@@ -783,6 +783,258 @@ rte_vhost_get_vhost_vring(int vid, uint16_t

vring_idx,

Quoted 70 lines
lib/librte_vhost/vhost.c +67 -0
 	return 0;
 }
 
+int
+rte_vhost_set_inflight_desc_split(int vid, uint16_t vring_idx,
+	uint16_t idx)
+{
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+
+	dev = get_device(vid);
+	if (unlikely(!dev))
+		return -1;
+
+	if (unlikely(!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))))
+		return 0;
+
+	if (unlikely(vq_is_packed(dev)))
+		return -1;
+
+	if (unlikely(vring_idx >= VHOST_MAX_VRING))
+		return -1;
+
+	vq = dev->virtqueue[vring_idx];
+	if (unlikely(!vq))
+		return -1;
+
+	if (unlikely(!vq->inflight_split))
+		return -1;
+
+	vq->inflight_split->desc[idx].counter = vq->global_counter++;
+	vq->inflight_split->desc[idx].inflight = 1;
+	return 0;
+}
+
+int
+rte_vhost_set_inflight_desc_packed(int vid, uint16_t vring_idx,
+	uint16_t head, uint16_t last, uint16_t *inflight_entry) {
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+	struct inflight_info_packed *inflight_info;
+	struct vring_packed_desc *desc;
+	uint16_t old_free_head, free_head;
+
+	dev = get_device(vid);
+	if (unlikely(!dev))
+		return -1;
+
+	if (unlikely(!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))))
+		return 0;
+
+	if (unlikely(!vq_is_packed(dev)))
+		return -1;
+
+	if (unlikely(vring_idx >= VHOST_MAX_VRING))
+		return -1;
+
+	vq = dev->virtqueue[vring_idx];
+	if (unlikely(!vq))
+		return -1;
+
+	inflight_info = vq->inflight_packed;
+	if (unlikely(!inflight_info))
+		return -1;
+
+	desc = vq->desc_packed;
+	old_free_head = inflight_info->old_free_head;
+	free_head = old_free_head;
Quoted 8 lines

lib/librte_vhost/vhost.c rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx, · line 858

Quoted 5 lines
lib/librte_vhost/vhost.c +5 -0
+
+	/* init header descriptor */
+	inflight_info->desc[old_free_head].num = 0;
+	inflight_info->desc[old_free_head].counter = vq->global_counter++;
+	inflight_info->desc[old_free_head].inflight = 1;

I think head has to be validated so that it does not causes out of bounds accesses.

Got it.

Quoted 47 lines
Quoted 47 lines
lib/librte_vhost/vhost.c +46 -0
+	/* save desc entry in flight entry */
+	while (head != ((last + 1) % vq->size)) {
+		inflight_info->desc[old_free_head].num++;
+		inflight_info->desc[free_head].addr = desc[head].addr;
+		inflight_info->desc[free_head].len = desc[head].len;
+		inflight_info->desc[free_head].flags = desc[head].flags;
+		inflight_info->desc[free_head].id = desc[head].id;
+
+		inflight_info->desc[old_free_head].last = free_head;
+		free_head = inflight_info->desc[free_head].next;
+		inflight_info->free_head = free_head;
+		head = (head + 1) % vq->size;
+	}
+
+	inflight_info->old_free_head = free_head;
+	*inflight_entry = old_free_head;
+
+	return 0;
+}
+
+int
+rte_vhost_clr_inflight_desc_split(int vid, uint16_t vring_idx,
+	uint16_t last_used_idx, uint16_t idx) {
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+
+	dev = get_device(vid);
+	if (unlikely(!dev))
+		return -1;
+
+	if (unlikely(!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))))
+		return 0;
+
+	if (unlikely(vq_is_packed(dev)))
+		return -1;
+
+	if (unlikely(vring_idx >= VHOST_MAX_VRING))
+		return -1;
+
+	vq = dev->virtqueue[vring_idx];
+	if (unlikely(!vq))
+		return -1;
+
+	if (unlikely(!vq->inflight_split))
+		return -1;
Quoted 9 lines

lib/librte_vhost/vhost.c rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx, · line 910

Quoted 4 lines
lib/librte_vhost/vhost.c +4 -0
+
+	rte_compiler_barrier();
+
+	vq->inflight_split->desc[idx].inflight = 0;

Maybe it would be better to check idx value, so that it does not causes out-of- bound accesses.

Got it.

Quoted 36 lines
Quoted 36 lines
lib/librte_vhost/vhost.c +36 -0
+
+	rte_compiler_barrier();
+
+	vq->inflight_split->used_idx = last_used_idx;
+	return 0;
+}
+
+int
+rte_vhost_clr_inflight_desc_packed(int vid, uint16_t vring_idx,
+	uint16_t head)
+{
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+	struct inflight_info_packed *inflight_info;
+
+	dev = get_device(vid);
+	if (unlikely(!dev))
+		return -1;
+
+	if (unlikely(!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))))
+		return 0;
+
+	if (unlikely(!vq_is_packed(dev)))
+		return -1;
+
+	if (unlikely(vring_idx >= VHOST_MAX_VRING))
+		return -1;
+
+	vq = dev->virtqueue[vring_idx];
+	if (unlikely(!vq))
+		return -1;
+
+	inflight_info = vq->inflight_packed;
+	if (unlikely(!inflight_info))
+		return -1;
Quoted 9 lines

lib/librte_vhost/vhost.c rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx, · line 950

Quoted 4 lines
lib/librte_vhost/vhost.c +4 -0
+
+	rte_compiler_barrier();
+
+	inflight_info->desc[head].inflight = 0;

Maybe it would be better to check head value, so that it does not causes out-of- bound accesses.

Got it.

Quoted 69 lines
Quoted 69 lines
lib/librte_vhost/vhost.c +68 -0
+	rte_compiler_barrier();
+
+	inflight_info->old_free_head = inflight_info->free_head;
+	inflight_info->old_used_idx = inflight_info->used_idx;
+	inflight_info->old_used_wrap_counter =
+inflight_info->used_wrap_counter;
+
+	return 0;
+}
+
+int
+rte_vhost_set_last_inflight_io_split(int vid, uint16_t vring_idx,
+	uint16_t idx)
+{
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+
+	dev = get_device(vid);
+	if (unlikely(!dev))
+		return -1;
+
+	if (unlikely(!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))))
+		return 0;
+
+	if (unlikely(vq_is_packed(dev)))
+		return -1;
+
+	if (unlikely(vring_idx >= VHOST_MAX_VRING))
+		return -1;
+
+	vq = dev->virtqueue[vring_idx];
+	if (unlikely(!vq))
+		return -1;
+
+	if (unlikely(!vq->inflight_split))
+		return -1;
+
+	vq->inflight_split->last_inflight_io = idx;
+	return 0;
+}
+
+int
+rte_vhost_set_last_inflight_io_packed(int vid, uint16_t vring_idx,
+	uint16_t head)
+{
+	struct virtio_net *dev;
+	struct vhost_virtqueue *vq;
+	struct inflight_info_packed *inflight_info;
+	uint16_t last;
+
+	dev = get_device(vid);
+	if (unlikely(!dev))
+		return -1;
+
+	if (unlikely(!(dev->protocol_features &
+		(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))))
+		return 0;
+
+	if (unlikely(!vq_is_packed(dev)))
+		return -1;
+
+	if (unlikely(vring_idx >= VHOST_MAX_VRING))
+		return -1;
+
+	vq = dev->virtqueue[vring_idx];
+	if (unlikely(!vq))
+		return -1;
Quoted 8 lines

lib/librte_vhost/vhost.c rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx, · line 1024

Quoted 6 lines
lib/librte_vhost/vhost.c +6 -0
+
+	inflight_info = vq->inflight_packed;
+	if (unlikely(!inflight_info))
+		return -1;
+
+	last = inflight_info->desc[head].last;

Ditto

Got it.

Quoted 7 lines
Quoted 7 lines
lib/librte_vhost/vhost.c +7 -0
+	inflight_info->desc[last].next = inflight_info->free_head;
+	inflight_info->free_head = head;
+	inflight_info->used_idx += inflight_info->desc[head].num;
+	if (inflight_info->used_idx >= inflight_info->desc_num) {
+		inflight_info->used_idx -= inflight_info->desc_num;
+		inflight_info->used_wrap_counter =
+			!inflight_info->used_wrap_counter;
Quoted 8 lines

lib/librte_vhost/vhost.c rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,

Quoted 8 lines
lib/librte_vhost/vhost.c +5 -0
+	}
+
+	return 0;
+}
+
 int
 rte_vhost_vring_call(int vid, uint16_t vring_idx)  {
 

Thanks.
Jin

author
#21 lore raw

PATCH v6 7/10 vhost: add APIs for user getting inflight ring

In reply to JinYu

This patch introduces two APIs. one is for getting inflgiht ring and the other is for getting base.

---
 lib/librte_vhost/rte_vhost.h | 40 ++++++++++++++++++++++++
 lib/librte_vhost/vhost.c     | 59 ++++++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+)
lib/librte_vhost/rte_vhost.h +40 -0
index d3b6eda21..dbe445e73 100644
@@ -693,6 +693,23 @@ int rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem);
 int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
 			      struct rte_vhost_vring *vring);
 
+/**
+ * Get guest inflight vring info, including inflight ring and resubmit list.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param vring
+ *  the structure to hold the requested inflight vring info
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_get_vhost_ring_inflight(int vid, uint16_t vring_idx,
+	struct rte_vhost_ring_inflight *vring);
+
 /**
  * Set split inflight descriptor.
  *
@@ -867,6 +884,29 @@ int __rte_experimental
 rte_vhost_get_vring_base(int vid, uint16_t queue_id,
 		uint16_t *last_avail_idx, uint16_t *last_used_idx);
 
+/**
+ * Get last_avail/last_used of the vhost virtqueue
+ *
+ * This function is designed for the reconnection and it's specific for
+ * the packed ring as we can get the two parameters from the inflight
+ * queueregion
+ *
+ * @param vid
+ *  vhost device ID
+ * @param queue_id
+ *  vhost queue index
+ * @param last_avail_idx
+ *  vhost last_avail_idx to get
+ * @param last_used_idx
+ *  vhost last_used_idx to get
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_get_vring_base_from_inflight(int vid,
+	uint16_t queue_id, uint16_t *last_avail_idx, uint16_t *last_used_idx);
+
 /**
  * Set last_avail/used_idx of the vhost virtqueue
  *
lib/librte_vhost/vhost.c +59 -0

71 lines not on this page · raw message

Signature · 1 line
2.17.2
#22 lore raw

Re: [dpdk-dev] [PATCH v6 07/10] vhost: add APIs for user getting inflight ring

Quoted 12 lines · JinYu

This patch introduces two APIs. one is for getting inflgiht ring and the other is for getting base.

---
 lib/librte_vhost/rte_vhost.h | 40 ++++++++++++++++++++++++
 lib/librte_vhost/vhost.c     | 59 ++++++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+)

PLease add these new APIs to the version map file.

author
#23 lore raw

Re: [dpdk-dev] [PATCH v6 07/10] vhost: add APIs for user getting inflight ring

Quoted 28 lines

-----Original Message-----
From: Maxime Coquelin [mailto:[email protected]]
Sent: Thursday, September 12, 2019 5:28 PM
To: Yu, Jin <[email protected]>; [email protected]
Cc: Liu, Changpeng <[email protected]>; Bie, Tiwei <[email protected]>; Wang, Zhihong <[email protected]>; Lin Li <[email protected]>; Xun Ni <[email protected]>; Yu Zhang <[email protected]>
Subject: Re: [PATCH v6 07/10] vhost: add APIs for user getting inflight ring

Quoted 12 lines · JinYu

This patch introduces two APIs. one is for getting inflgiht ring and the other is for getting base.

---
 lib/librte_vhost/rte_vhost.h | 40 ++++++++++++++++++++++++
 lib/librte_vhost/vhost.c     | 59 ++++++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+)
Quoted 1 line

PLease add these new APIs to the version map file.

It's my fault, I just forgot to add these APIs to version map file. Will fix it in next version.

Thanks.

author
#24 lore raw

PATCH v6 8/10 vhost: fix vring functions to support packed ring

In reply to JinYu

This patch fix two APIs so user can get the packed ring support.

Fixes fceec568 (vhost: add packed ring)
---
 lib/librte_vhost/vhost.c | 68 +++++++++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 19 deletions(-)
lib/librte_vhost/vhost.c +49 -19
index 2cc2793c4..44c4bb661 100644
@@ -771,9 +771,15 @@ rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
 	if (!vq)
 		return -1;
 
-	vring->desc  = vq->desc;
-	vring->avail = vq->avail;
-	vring->used  = vq->used;
+	if (vq_is_packed(dev)) {
+		vring->desc_packed = vq->desc_packed;
+		vring->driver_event = vq->driver_event;
+		vring->device_event = vq->device_event;
+	} else {
+		vring->desc = vq->desc;
+		vring->avail = vq->avail;
+		vring->used = vq->used;
+	}
 	vring->log_guest_addr  = vq->log_guest_addr;
 
 	vring->callfd  = vq->callfd;
@@ -1253,13 +1259,51 @@ int rte_vhost_get_log_base(int vid, uint64_t *log_base,
 int rte_vhost_get_vring_base(int vid, uint16_t queue_id,
 		uint16_t *last_avail_idx, uint16_t *last_used_idx)
 {
+	struct vhost_virtqueue *vq;
 	struct virtio_net *dev = get_device(vid);
 
 	if (dev == NULL || last_avail_idx == NULL || last_used_idx == NULL)
 		return -1;
 
-	*last_avail_idx = dev->virtqueue[queue_id]->last_avail_idx;
-	*last_used_idx = dev->virtqueue[queue_id]->last_used_idx;
+	vq = dev->virtqueue[queue_id];
+	if (!vq)
+		return -1;
+
+	if (vq_is_packed(dev)) {
+		*last_avail_idx = (vq->avail_wrap_counter << 15) |
+					vq->last_avail_idx;
+		*last_used_idx = (vq->used_wrap_counter << 15) |
+					vq->last_used_idx;
+	} else {
+		*last_avail_idx = vq->last_avail_idx;
+		*last_used_idx = vq->last_used_idx;
+	}
+
+	return 0;
+}
+
+int rte_vhost_set_vring_base(int vid, uint16_t queue_id,
+		uint16_t last_avail_idx, uint16_t last_used_idx)
+{
+	struct vhost_virtqueue *vq;
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return -1;
+
+	vq = dev->virtqueue[queue_id];
+	if (!vq)
+		return -1;
+
+	if (vq_is_packed(dev)) {
+		vq->last_avail_idx = last_avail_idx & 0x7fff;
+		vq->avail_wrap_counter = !!(last_avail_idx & (1 << 15));
+		vq->last_used_idx = last_used_idx & 0x7fff;
+		vq->used_wrap_counter = !!(last_used_idx & (1 << 15));
+	} else {
+		vq->last_avail_idx = last_avail_idx;
+		vq->last_used_idx = last_used_idx;
+	}
 
 	return 0;
 }
@@ -1288,20 +1332,6 @@ rte_vhost_get_vring_base_from_inflight(int vid,
 	return 0;
 }
 
-int rte_vhost_set_vring_base(int vid, uint16_t queue_id,
-		uint16_t last_avail_idx, uint16_t last_used_idx)
-{
-	struct virtio_net *dev = get_device(vid);
-
-	if (!dev)
-		return -1;
-
-	dev->virtqueue[queue_id]->last_avail_idx = last_avail_idx;
-	dev->virtqueue[queue_id]->last_used_idx = last_used_idx;
-
-	return 0;
-}
-
 int rte_vhost_extern_callback_register(int vid,
 		struct rte_vhost_user_extern_ops const * const ops, void *ctx)
 {
Signature · 1 line
2.17.2
author
#25 lore raw

PATCH v6 9/10 vhost: add an API for judging vq format

In reply to JinYu

This patch introduces an API for getting virtqueue format.

---
 lib/librte_vhost/rte_vhost.h | 13 +++++++++++++
 lib/librte_vhost/vhost.c     | 12 ++++++++++++
 2 files changed, 25 insertions(+)
lib/librte_vhost/rte_vhost.h +13 -0
index dbe445e73..185c3af8a 100644
@@ -11,6 +11,7 @@
  */
 
 #include <stdint.h>
+#include <stdbool.h>
 #include <sys/eventfd.h>
 
 #include <rte_memory.h>
@@ -678,6 +679,18 @@ uint16_t rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
  */
 int rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem);
 
+/**
+ * Get vq is packed
+ *
+ * @param vid
+ *  vhost device ID
+ * @return
+ *  true on packed, false on split
+ */
+__rte_experimental
+bool
+rte_vhost_vq_is_packed(int vid);
+
 /**
  * Get guest vring info, including the vring address, vring size, etc.
  *
lib/librte_vhost/vhost.c +12 -0
index 44c4bb661..255fcfd0a 100644
@@ -753,6 +753,18 @@ rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem)
 	return 0;
 }
 
+bool
+rte_vhost_vq_is_packed(int vid)
+{
+	struct virtio_net *dev;
+
+	dev = get_device(vid);
+	if (unlikely(!dev))
+		return -1;
+
+	return vq_is_packed(dev);
+}
+
 int
 rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
 			  struct rte_vhost_vring *vring)
Signature · 1 line
2.17.2
author
#26 lore raw

PATCH v6 10/10 vhost: add vhost-user-blk example which support inflight

In reply to JinYu

A vhost-user-blk example that support inflight feature. It uses the new APIs that introduced in the first patch, so It can show how there APIs work to support inflight feature.

---
V1 - add the case.
V2 - add the rte_vhost prefix.
V3 - add packed ring support

---
 examples/vhost_blk/Makefile           |   67 ++
 examples/vhost_blk/blk.c              |  125 +++
 examples/vhost_blk/blk_spec.h         |   95 ++
 examples/vhost_blk/meson.build        |   20 +
 examples/vhost_blk/vhost_blk.c        | 1313 +++++++++++++++++++++++++
 examples/vhost_blk/vhost_blk.h        |  116 +++
 examples/vhost_blk/vhost_blk_compat.c |  195 ++++
 7 files changed, 1931 insertions(+)
 create mode 100644 examples/vhost_blk/Makefile
 create mode 100644 examples/vhost_blk/blk.c
 create mode 100644 examples/vhost_blk/blk_spec.h
 create mode 100644 examples/vhost_blk/meson.build
 create mode 100644 examples/vhost_blk/vhost_blk.c
 create mode 100644 examples/vhost_blk/vhost_blk.h
 create mode 100644 examples/vhost_blk/vhost_blk_compat.c
examples/vhost_blk/Makefile new file +67 -0
new file mode 100644
index 000000000..52e9befd8
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2010-2017 Intel Corporation
+
+# binary name
+APP = vhost-blk
+
+# all source are stored in SRCS-y
+SRCS-y := blk.c vhost_blk.c vhost_blk_compat.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+	ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+	ln -sf $(APP)-static build/$(APP)
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+LDFLAGS += -pthread
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+	$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+	$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+	@mkdir -p $@
+
+.PHONY: clean
+clean:
+	rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+	test -d build && rmdir -p build || true
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, detect a build directory, by looking for a path with a .config
+RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config)))))
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUX),y)
+$(info This application can only operate in a linux environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+else
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+CFLAGS += -O2
+#CFLAGS += $(WERROR_FLAGS)
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+
+endif
+endif
examples/vhost_blk/blk.c new file +125 -0

125 lines not on this page · raw message

examples/vhost_blk/blk_spec.h new file +95 -0

95 lines not on this page · raw message

examples/vhost_blk/meson.build new file +20 -0
new file mode 100644
index 000000000..028aa4f62
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2017 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+if not is_linux
+	build = false
+endif
+
+if not cc.has_header('linux/virtio_blk.h')
+	build = false
+endif
+
+deps += 'vhost'
+sources = files(
+	'blk.c', 'vhost_blk.c', 'vhost_blk_compat.c'
+)
examples/vhost_blk/vhost_blk.c new file +1313 -0

1,313 lines not on this page · raw message

examples/vhost_blk/vhost_blk.h new file +116 -0

116 lines not on this page · raw message

examples/vhost_blk/vhost_blk_compat.c new file +195 -0

195 lines not on this page · raw message

Signature · 1 line
2.17.2
#27 lore raw
In reply to JinYu

Hi Jin,

I see in this patch set there are several callings rte_compiler_barrier() which is sufficient for x86 but not for aarch64/ppc and other weaker memory model architectures. EAL has defined coherent memory io barriers(I think this should be the right barrier) for mutli-arch support. Could you change these barriers to rte_cio_r/wmb barriers?
http://git.dpdk.org/dpdk/tree/lib/librte_eal/common/include/generic/rte_atomic.h#n110

Best Regards,
Gavin

Quoted 74 lines

-----Original Message-----
From: dev <[email protected]> On Behalf Of JinYu
Sent: Thursday, August 29, 2019 10:12 PM
To: [email protected]
Cc: [email protected]; [email protected]; [email protected]; [email protected]; JinYu <[email protected]>
Subject: [dpdk-dev] [PATCH v6 00/10] vhost: support inflight share memory protocol feature

This patches introduces two new messages VHOST_USER_GET_INFLIGHT_FD
and VHOST_USER_SET_INFLIGHT_FD to support transferring a shared buffer between qemu and backend for backend reconnection. Now It can both support split and packed ring. The example code show how these APIs work. The test has passed.

How to test the example:
1, Qemu need a patch.
https://patchwork.kernel.org/patch/10861411/
it also needs some manual modifications:
we should confirm that before we send get inflight we have already sent the set features but it seems Qemu didn't do like this. So we manually revise this, we can add below code in vhost_dev_get_inflight

    int r;

    r = vhost_dev_set_features(dev, dev->log_enabled);
    if (r < 0) {
        return -errno;
    }

before get_inflight_fd.
2, Guest OS version >= 5.0
3, run the example
4, run the qemu with vhost-user-blk-pci.
eg:

        -chardev socket,id=spdk_vhost_blk0,reconnect=1,path=xxxx\
        -device vhost-user-blk-

pci,ring_packed=on,chardev=spdk_vhost_blk0,num-queues=1\
5, run fio in the guest
6, kill the example and run again.
7, the fio in the guest should continue run without errors.

JinYu (10):
vhost: add the inflight description
vhost: add packed ring
vhost: add the inflight structure
vhost: add two new messages to support a shared buffer
vhost: checkout and cleanup the resubmit inflight information
vhost: add the APIs to operate inflight ring
vhost: add APIs for user getting inflight ring
vhost: fix vring functions to support packed ring
vhost: add an API for judging vq format
vhost: add vhost-user-blk example which support inflight

 examples/vhost_blk/Makefile           |   67 ++
 examples/vhost_blk/blk.c              |  125 +++
 examples/vhost_blk/blk_spec.h         |   95 ++
 examples/vhost_blk/meson.build        |   20 +
 examples/vhost_blk/vhost_blk.c        | 1313 +++++++++++++++++++++++++
 examples/vhost_blk/vhost_blk.h        |  116 +++
 examples/vhost_blk/vhost_blk_compat.c |  195 ++++
 lib/librte_vhost/rte_vhost.h          |  250 ++++-
 lib/librte_vhost/vhost.c              |  396 +++++++-
 lib/librte_vhost/vhost.h              |   16 +
 lib/librte_vhost/vhost_user.c         |  439 +++++++++
 lib/librte_vhost/vhost_user.h         |   12 +-
 12 files changed, 3032 insertions(+), 12 deletions(-)
 create mode 100644 examples/vhost_blk/Makefile
 create mode 100644 examples/vhost_blk/blk.c
 create mode 100644 examples/vhost_blk/blk_spec.h
 create mode 100644 examples/vhost_blk/meson.build
 create mode 100644 examples/vhost_blk/vhost_blk.c
 create mode 100644 examples/vhost_blk/vhost_blk.h
 create mode 100644 examples/vhost_blk/vhost_blk_compat.c
Quoted 2 lines

--
2.17.2

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

#28 lore raw
In reply to JinYu
Quoted 13 lines · JinYu

This patches introduces two new messages VHOST_USER_GET_INFLIGHT_FD and VHOST_USER_SET_INFLIGHT_FD to support transferring a shared buffer between qemu and backend for backend reconnection. Now It can both support split and packed ring. The example code show how these APIs work. The test has passed.

How to test the example:
1, Qemu need a patch.
https://patchwork.kernel.org/patch/10861411/
it also needs some manual modifications:
we should confirm that before we send get inflight we have already sent the set features but it seems Qemu didn't do like this. So we manually revise this, we can add below code in vhost_dev_get_inflight

Quoted 6 lines
    int r;

    r = vhost_dev_set_features(dev, dev->log_enabled);
    if (r < 0) {
        return -errno;
    }

Are you working on fixing that upstream?
What happens if we don't do these modifications and apply your series? Would it be considered as a regression?

author
#29 lore raw
Quoted 29 lines

-----Original Message-----
From: Maxime Coquelin [mailto:[email protected]]
Sent: Saturday, September 7, 2019 12:36 AM
To: Yu, Jin <[email protected]>; [email protected]
Cc: Liu, Changpeng <[email protected]>; Bie, Tiwei <[email protected]>; Wang, Zhihong <[email protected]>
Subject: Re: [PATCH v6 00/10] vhost: support inflight share memory protocol feature

Quoted 1 line · JinYu

This patches introduces two new messages

VHOST_USER_GET_INFLIGHT_FD

Quoted 1 line

and VHOST_USER_SET_INFLIGHT_FD to support transferring a shared

buffer

Quoted 13 lines

between qemu and backend for backend reconnection.
Now It can both support split and packed ring. The example code show how these APIs work. The test has passed.

How to test the example:
1, Qemu need a patch.
https://patchwork.kernel.org/patch/10861411/
it also needs some manual modifications:
we should confirm that before we send get inflight we have already sent the set features but it seems Qemu didn't do like this. So we manually revise this, we can add below code in vhost_dev_get_inflight

    int r;
Quoted 8 lines
Quoted 4 lines
    r = vhost_dev_set_features(dev, dev->log_enabled);
    if (r < 0) {
        return -errno;
    }

Are you working on fixing that upstream?
What happens if we don't do these modifications and apply your series? Would it be considered as a regression?

Hi Maxime,
Actually I didn't fix the upstream.
Without these modifications, get_inflight_fd and set_inflight_fd can't confirm the dev packet format. So the inflight ring format may always be split.
Thanks.