Skip to contentSkip to conversation

vhost: support inflight share memory protocol feature

PATCH Superseded JinYu 2 participants 7 messages Jun 26, 2019 – Jul 8, 2019

v1 of 11 Superseded Latest is v11 →

lore
Share & tools
lore

JinYu

author
#0 lore raw

PATCH 1/1 vhost: support inflight share memory protocol feature

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.

Firstly, qemu uses VHOST_USER_GET_INFLIGHT_FD to get the shared buffer from backend. Then qemu should send it back through VHOST_USER_SET_INFLIGHT_FD each time we start vhost-user.

This shared buffer is used to process inflight I/O when backend reconnect.

---
V1 - specify the APIs are split-ring only

---
 lib/librte_vhost/rte_vhost.h           |  99 +++++++++
 lib/librte_vhost/rte_vhost_version.map |   4 +
 lib/librte_vhost/vhost.c               | 135 ++++++++++++
 lib/librte_vhost/vhost.h               |  12 +
 lib/librte_vhost/vhost_user.c          | 292 +++++++++++++++++++++++++
 lib/librte_vhost/vhost_user.h          |  13 +-
 6 files changed, 554 insertions(+), 1 deletion(-)
lib/librte_vhost/rte_vhost.h +99 -0
index 0226b3eff..c9959c15a 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
@@ -98,12 +102,41 @@ 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 resubmit_desc {
+	uint16_t index;
+	uint64_t counter;
+};
+
+struct resubmit_info {
+	struct resubmit_desc	*resubmit_list;
+	uint16_t		resubmit_num;
+};
+
 struct rte_vhost_vring {
 	struct vring_desc	*desc;
 	struct vring_avail	*avail;
 	struct vring_used	*used;
 	uint64_t		log_guest_addr;
 
+	struct inflight_info_split *inflight;
+	struct resubmit_info	*resubmit_inflight;
+
 	/** Deprecated, use rte_vhost_vring_call() instead. */
 	int			callfd;
 
@@ -603,6 +636,22 @@ 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 guest vring info, including the vring address, vring size, inflight, etc.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param vring
+ *  the structure to hold the requested vring info
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_get_vhost_vring_with_inflight_split(int vid, uint16_t vring_idx,
+			      struct rte_vhost_vring *vring);
+
 /**
  * Get guest vring info, including the vring address, vring size, etc.
  *
@@ -631,6 +680,56 @@ int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
  */
 int rte_vhost_vring_call(int vid, uint16_t vring_idx);
 
+/**
+ * set inflight flag for a desc.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_set_inflight_desc_split(int vid, uint16_t vring_idx,
+		uint16_t idx);
+
+/**
+ * clear inflight flag for a desc.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param last_used_idx
+ *  next free used_idx
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_clr_inflight_desc_split(int vid, uint16_t vring_idx,
+		uint16_t last_used_idx, uint16_t idx);
+
+/**
+ * set last inflight io index.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_set_last_inflight_io_split(int vid, uint16_t vring_idx,
+		uint16_t idx);
+
 /**
  * Get vhost RX queue avail count.
  *
lib/librte_vhost/rte_vhost_version.map +4 -0
index 5f1d4a75c..709593701 100644
@@ -87,4 +87,8 @@ EXPERIMENTAL {
 	rte_vdpa_relay_vring_used;
 	rte_vhost_extern_callback_register;
 	rte_vhost_driver_set_protocol_features;
+	rte_vhost_set_inflight_desc_split;
+	rte_vhost_clr_inflight_desc_split;
+	rte_vhost_set_last_inflight_io_split;
+	rte_vhost_get_vhost_vring_with_inflight_split;
 };
lib/librte_vhost/vhost.c +135 -0

153 lines not on this page · raw message

lib/librte_vhost/vhost.h +12 -0
index 884befa85..c18356c15 100644
@@ -128,6 +128,11 @@ struct vhost_virtqueue {
 	/* Physical address of used ring, for logging */
 	uint64_t		log_guest_addr;
 
+	/* Inflight share memory info */
+	struct inflight_info_split *inflight;
+	struct resubmit_info	*resubmit_inflight;
+	uint64_t		counter;
+
 	uint16_t		nr_zmbuf;
 	uint16_t		zmbuf_size;
 	uint16_t		last_zmbuf_idx;
@@ -286,6 +291,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 +314,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 +292 -0

340 lines not on this page · raw message

lib/librte_vhost/vhost_user.h +12 -1
index 2a650fe4b..99a773910 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 {
@@ -112,6 +114,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 */
@@ -131,6 +140,7 @@ typedef struct VhostUserMsg {
 		struct vhost_vring_addr addr;
 		VhostUserMemory memory;
 		VhostUserLog    log;
+		VhostUserInflight inflight;
 		struct vhost_iotlb_msg iotlb;
 		VhostUserCryptoSessionParam crypto_session;
 		VhostUserVringArea area;
@@ -148,6 +158,7 @@ typedef struct VhostUserMsg {
 /* vhost_user.c */
 int vhost_user_msg_handler(int vid, int fd);
 int vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm);
+void *inflight_mem_alloc(const char *name, size_t size, int *fd);
 
 /* socket.c */
 int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
Signature · 1 line
2.17.2
#1 lore raw

Hi Jin,

Quoted 70 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.

Firstly, qemu uses VHOST_USER_GET_INFLIGHT_FD to get the shared buffer from backend. Then qemu should send it back through VHOST_USER_SET_INFLIGHT_FD each time we start vhost-user.

This shared buffer is used to process inflight I/O when backend reconnect.

---
V1 - specify the APIs are split-ring only

---
  lib/librte_vhost/rte_vhost.h           |  99 +++++++++
  lib/librte_vhost/rte_vhost_version.map |   4 +
  lib/librte_vhost/vhost.c               | 135 ++++++++++++
  lib/librte_vhost/vhost.h               |  12 +
  lib/librte_vhost/vhost_user.c          | 292 +++++++++++++++++++++++++
  lib/librte_vhost/vhost_user.h          |  13 +-
  6 files changed, 554 insertions(+), 1 deletion(-)
lib/librte_vhost/rte_vhost.h +29 -0
index 0226b3eff..c9959c15a 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
@@ -98,12 +102,41 @@ 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 resubmit_desc {
+	uint16_t index;
+	uint64_t counter;
+};
+
+struct resubmit_info {
+	struct resubmit_desc	*resubmit_list;
+	uint16_t		resubmit_num;
+};

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

Quoted 10 lines
lib/librte_vhost/rte_vhost.h +4 -0
+
  struct rte_vhost_vring {
  	struct vring_desc	*desc;
  	struct vring_avail	*avail;
  	struct vring_used	*used;
  	uint64_t		log_guest_addr;
 
+	struct inflight_info_split *inflight;
+	struct resubmit_info	*resubmit_inflight;
+

This is breaking the ABI, and discussing with Tiwei, we think it could be avoided by defining its own structure of inflight and inflight resubmit pointers. More below:

Quoted 12 lines
lib/librte_vhost/rte_vhost.h +5 -0
  	/** Deprecated, use rte_vhost_vring_call() instead. */
  	int			callfd;
 
@@ -603,6 +636,22 @@ 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 guest vring info, including the vring address, vring size, inflight, etc.
+ *
+ * @param vid
+ *  vhost device ID

lib/librte_vhost/rte_vhost.h uint16_t rte_vhost_dequeue_burst(int vid, uint16_t queue_id, · line 653

Quoted 10 lines
lib/librte_vhost/rte_vhost.h +10 -0
+ * @param vring_idx
+ *  vring index
+ * @param vring
+ *  the structure to hold the requested vring info
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_get_vhost_vring_with_inflight_split(int vid, uint16_t vring_idx,
+			      struct rte_vhost_vring *vring);

Here a new API is introduced to get vting info with inflight. It could be just changed to get only the inflight info. It means the caller would first call rte_vhost_get_vhost_vring() and then the new function, which I guess may be renamed to:

rte_vhost_get_vhost_vring_inflight_split

Other than that, the patch looks good to me.

(Next time, please run get_maintainer.sh script so that all the maintainers are in Cc:).

Thanks,
Maxime

author
#2 lore raw
Quoted 89 lines

From: Maxime Coquelin [mailto:[email protected]]
Sent: Friday, July 5, 2019 4:47 PM
To: Yu, Jin <[email protected]>; [email protected]
Cc: Liu, Changpeng <[email protected]>; LinLi <[email protected]>; XunNi <[email protected]>; YuZhang <[email protected]>; Bie, Tiwei <[email protected]>
Subject: Re: [dpdk-dev] [PATCH] [v1]vhost: support inflight share memory protocol feature

Hi Jin,

Quoted 1 line · JinYu

This patch introduces two new messages VHOST_USER_GET_INFLIGHT_FD

and

Quoted 75 lines

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

Firstly, qemu uses VHOST_USER_GET_INFLIGHT_FD to get the shared buffer from backend. Then qemu should send it back through VHOST_USER_SET_INFLIGHT_FD each time we start vhost-user.

This shared buffer is used to process inflight I/O when backend reconnect.

---
V1 - specify the APIs are split-ring only

---
  lib/librte_vhost/rte_vhost.h           |  99 +++++++++
  lib/librte_vhost/rte_vhost_version.map |   4 +
  lib/librte_vhost/vhost.c               | 135 ++++++++++++
  lib/librte_vhost/vhost.h               |  12 +
  lib/librte_vhost/vhost_user.c          | 292 +++++++++++++++++++++++++
  lib/librte_vhost/vhost_user.h          |  13 +-
  6 files changed, 554 insertions(+), 1 deletion(-)
(quoted diff) +0 -0

b/lib/librte_vhost/rte_vhost.h index 0226b3eff..c9959c15a 100644

lib/librte_vhost/rte_vhost.h +29 -0
@@ -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
@@ -98,12 +102,41 @@ 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 resubmit_desc {
+	uint16_t index;
+	uint64_t counter;
+};
+
+struct resubmit_info {
+	struct resubmit_desc	*resubmit_list;
+	uint16_t		resubmit_num;
+};
+
  struct rte_vhost_vring {
  	struct vring_desc	*desc;
  	struct vring_avail	*avail;
  	struct vring_used	*used;
  	uint64_t		log_guest_addr;
 
Quoted 7 lines

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

Quoted 3 lines
lib/librte_vhost/rte_vhost.h +3 -0
+	struct inflight_info_split *inflight;
+	struct resubmit_info	*resubmit_inflight;
+

This is breaking the ABI, and discussing with Tiwei, we think it could be avoided by defining its own structure of inflight and inflight resubmit pointers. More below:

So you means that define a new struct such as struct rte_vhost_inflight_ring?

Quoted 30 lines

lib/librte_vhost/rte_vhost.h uint16_t rte_vhost_dequeue_burst(int vid,

Quoted 5 lines
lib/librte_vhost/rte_vhost.h +0 -0
  	/** Deprecated, use rte_vhost_vring_call() instead. */
  	int			callfd;
 
@@ -603,6 +636,22 @@ uint16_t rte_vhost_dequeue_burst(int vid,

uint16_t queue_id,

Quoted 8 lines
lib/librte_vhost/rte_vhost.h +5 -0
   */
  int rte_vhost_get_mem_table(int vid, struct rte_vhost_memory **mem);
 
+/**
+ * Get guest vring info, including the vring address, vring size, inflight, etc.
+ *
+ * @param vid
+ *  vhost device ID

lib/librte_vhost/rte_vhost.h uint16_t rte_vhost_dequeue_burst(int vid, uint16_t queue_id, · line 653

Quoted 10 lines
lib/librte_vhost/rte_vhost.h +10 -0
+ * @param vring_idx
+ *  vring index
+ * @param vring
+ *  the structure to hold the requested vring info
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_get_vhost_vring_with_inflight_split(int vid, uint16_t vring_idx,
+			      struct rte_vhost_vring *vring);

Here a new API is introduced to get vting info with inflight.
It could be just changed to get only the inflight info. It means the caller would first call rte_vhost_get_vhost_vring() and then the new function, which I guess may be renamed to:

Quoted 1 line

rte_vhost_get_vhost_vring_inflight_split

Got It.

Quoted 8 lines

Other than that, the patch looks good to me.

(Next time, please run get_maintainer.sh script so that all the maintainers are in Cc:).

Thanks,
Maxime

Thanks Maxime, also I will submit an example code of vhost_user_blk which support the inflight feature. It can show how these APIs work.

Thanks
Jin

author
#3 lore raw

PATCH v2 1/2 vhost: support inflight share memory protocol feature

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.

Firstly, qemu uses VHOST_USER_GET_INFLIGHT_FD to get the shared buffer from backend. Then qemu should send it back through VHOST_USER_SET_INFLIGHT_FD each time we start vhost-user.

This shared buffer is used to process inflight I/O when backend reconnect.

---
v1 - specify the APIs are split-ring only
v2 - fix APIs and judge split or packed

---
 lib/librte_vhost/rte_vhost.h           | 105 +++++++++
 lib/librte_vhost/rte_vhost_version.map |   4 +
 lib/librte_vhost/vhost.c               | 158 ++++++++++++-
 lib/librte_vhost/vhost.h               |  16 ++
 lib/librte_vhost/vhost_user.c          | 313 +++++++++++++++++++++++++
 lib/librte_vhost/vhost_user.h          |  13 +-
 6 files changed, 607 insertions(+), 2 deletions(-)
lib/librte_vhost/rte_vhost.h +105 -0
index 0226b3eff..a17aff876 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
@@ -98,6 +102,41 @@ 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 resubmit_desc {
+	uint16_t index;
+	uint64_t counter;
+};
+
+struct resubmit_info {
+	struct resubmit_desc	*resubmit_list;
+	uint16_t		resubmit_num;
+};
+
+struct rte_vhost_ring_inflight_split {
+	union {
+		struct inflight_info_split *inflight_split;
+		/* TODO */
+	};
+
+	struct resubmit_info *resubmit_inflight_split;
+};
+
 struct rte_vhost_vring {
 	struct vring_desc	*desc;
 	struct vring_avail	*avail;
@@ -603,6 +642,22 @@ 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 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
+ */
+int __rte_experimental
+rte_vhost_get_vhost_ring_inflight_split(int vid, uint16_t vring_idx,
+			      struct rte_vhost_ring_inflight_split *vring);
+
 /**
  * Get guest vring info, including the vring address, vring size, etc.
  *
@@ -631,6 +686,56 @@ int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
  */
 int rte_vhost_vring_call(int vid, uint16_t vring_idx);
 
+/**
+ * set inflight flag for a desc.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_set_inflight_desc_split(int vid, uint16_t vring_idx,
+		uint16_t idx);
+
+/**
+ * clear inflight flag for a desc.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param last_used_idx
+ *  next free used_idx
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_clr_inflight_desc_split(int vid, uint16_t vring_idx,
+		uint16_t last_used_idx, uint16_t idx);
+
+/**
+ * set last inflight io index.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_set_last_inflight_io_split(int vid, uint16_t vring_idx,
+		uint16_t idx);
+
 /**
  * Get vhost RX queue avail count.
  *
lib/librte_vhost/rte_vhost_version.map +4 -0
index 5f1d4a75c..709593701 100644
@@ -87,4 +87,8 @@ EXPERIMENTAL {
 	rte_vdpa_relay_vring_used;
 	rte_vhost_extern_callback_register;
 	rte_vhost_driver_set_protocol_features;
+	rte_vhost_set_inflight_desc_split;
+	rte_vhost_clr_inflight_desc_split;
+	rte_vhost_set_last_inflight_io_split;
+	rte_vhost_get_vhost_vring_with_inflight_split;
 };
lib/librte_vhost/vhost.c +157 -1

183 lines not on this page · raw message

lib/librte_vhost/vhost.h +16 -0
index 884befa85..22925586d 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;
+		/* TODO */
+	};
+	struct resubmit_info *resubmit_inflight_split;
+	uint64_t		global_counter;
+
 	uint16_t		nr_zmbuf;
 	uint16_t		zmbuf_size;
 	uint16_t		last_zmbuf_idx;
@@ -286,6 +294,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 +317,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;
@@ -467,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_split(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 +313 -0

367 lines not on this page · raw message

lib/librte_vhost/vhost_user.h +12 -1
index 2a650fe4b..99a773910 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 {
@@ -112,6 +114,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 */
@@ -131,6 +140,7 @@ typedef struct VhostUserMsg {
 		struct vhost_vring_addr addr;
 		VhostUserMemory memory;
 		VhostUserLog    log;
+		VhostUserInflight inflight;
 		struct vhost_iotlb_msg iotlb;
 		VhostUserCryptoSessionParam crypto_session;
 		VhostUserVringArea area;
@@ -148,6 +158,7 @@ typedef struct VhostUserMsg {
 /* vhost_user.c */
 int vhost_user_msg_handler(int vid, int fd);
 int vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm);
+void *inflight_mem_alloc(const char *name, size_t size, int *fd);
 
 /* socket.c */
 int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
Signature · 1 line
2.17.2
author
#4 lore raw

PATCH v2 1/2 vhost: support inflight share memory protocol feature

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.

Firstly, qemu uses VHOST_USER_GET_INFLIGHT_FD to get the shared buffer from backend. Then qemu should send it back through VHOST_USER_SET_INFLIGHT_FD each time we start vhost-user.

This shared buffer is used to process inflight I/O when backend reconnect.

---
v1 - specify the APIs are split-ring only
v2 - fix APIs and judge split or packed

---
 lib/librte_vhost/rte_vhost.h           | 105 +++++++++
 lib/librte_vhost/rte_vhost_version.map |   4 +
 lib/librte_vhost/vhost.c               | 158 ++++++++++++-
 lib/librte_vhost/vhost.h               |  16 ++
 lib/librte_vhost/vhost_user.c          | 313 +++++++++++++++++++++++++
 lib/librte_vhost/vhost_user.h          |  13 +-
 6 files changed, 607 insertions(+), 2 deletions(-)
lib/librte_vhost/rte_vhost.h +105 -0
index 0226b3eff..a17aff876 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
@@ -98,6 +102,41 @@ 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 resubmit_desc {
+	uint16_t index;
+	uint64_t counter;
+};
+
+struct resubmit_info {
+	struct resubmit_desc	*resubmit_list;
+	uint16_t		resubmit_num;
+};
+
+struct rte_vhost_ring_inflight_split {
+	union {
+		struct inflight_info_split *inflight_split;
+		/* TODO */
+	};
+
+	struct resubmit_info *resubmit_inflight_split;
+};
+
 struct rte_vhost_vring {
 	struct vring_desc	*desc;
 	struct vring_avail	*avail;
@@ -603,6 +642,22 @@ 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 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
+ */
+int __rte_experimental
+rte_vhost_get_vhost_ring_inflight_split(int vid, uint16_t vring_idx,
+			      struct rte_vhost_ring_inflight_split *vring);
+
 /**
  * Get guest vring info, including the vring address, vring size, etc.
  *
@@ -631,6 +686,56 @@ int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
  */
 int rte_vhost_vring_call(int vid, uint16_t vring_idx);
 
+/**
+ * set inflight flag for a desc.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_set_inflight_desc_split(int vid, uint16_t vring_idx,
+		uint16_t idx);
+
+/**
+ * clear inflight flag for a desc.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param last_used_idx
+ *  next free used_idx
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_clr_inflight_desc_split(int vid, uint16_t vring_idx,
+		uint16_t last_used_idx, uint16_t idx);
+
+/**
+ * set last inflight io index.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_set_last_inflight_io_split(int vid, uint16_t vring_idx,
+		uint16_t idx);
+
 /**
  * Get vhost RX queue avail count.
  *
lib/librte_vhost/rte_vhost_version.map +4 -0
index 5f1d4a75c..709593701 100644
@@ -87,4 +87,8 @@ EXPERIMENTAL {
 	rte_vdpa_relay_vring_used;
 	rte_vhost_extern_callback_register;
 	rte_vhost_driver_set_protocol_features;
+	rte_vhost_set_inflight_desc_split;
+	rte_vhost_clr_inflight_desc_split;
+	rte_vhost_set_last_inflight_io_split;
+	rte_vhost_get_vhost_vring_with_inflight_split;
 };
lib/librte_vhost/vhost.c +157 -1

183 lines not on this page · raw message

lib/librte_vhost/vhost.h +16 -0
index 884befa85..22925586d 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;
+		/* TODO */
+	};
+	struct resubmit_info *resubmit_inflight_split;
+	uint64_t		global_counter;
+
 	uint16_t		nr_zmbuf;
 	uint16_t		zmbuf_size;
 	uint16_t		last_zmbuf_idx;
@@ -286,6 +294,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 +317,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;
@@ -467,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_split(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 +313 -0

367 lines not on this page · raw message

lib/librte_vhost/vhost_user.h +12 -1
index 2a650fe4b..99a773910 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 {
@@ -112,6 +114,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 */
@@ -131,6 +140,7 @@ typedef struct VhostUserMsg {
 		struct vhost_vring_addr addr;
 		VhostUserMemory memory;
 		VhostUserLog    log;
+		VhostUserInflight inflight;
 		struct vhost_iotlb_msg iotlb;
 		VhostUserCryptoSessionParam crypto_session;
 		VhostUserVringArea area;
@@ -148,6 +158,7 @@ typedef struct VhostUserMsg {
 /* vhost_user.c */
 int vhost_user_msg_handler(int vid, int fd);
 int vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm);
+void *inflight_mem_alloc(const char *name, size_t size, int *fd);
 
 /* socket.c */
 int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
Signature · 1 line
2.17.2
author
#5 lore raw

PATCH v2 1/2 vhost: support inflight share memory protocol feature

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.

Firstly, qemu uses VHOST_USER_GET_INFLIGHT_FD to get the shared buffer from backend. Then qemu should send it back through VHOST_USER_SET_INFLIGHT_FD each time we start vhost-user.

This shared buffer is used to process inflight I/O when backend reconnect.

---
v1 - specify the APIs are split-ring only
v2 - fix APIs and judge split or packed

---
 lib/librte_vhost/rte_vhost.h           | 105 +++++++++
 lib/librte_vhost/rte_vhost_version.map |   4 +
 lib/librte_vhost/vhost.c               | 158 ++++++++++++-
 lib/librte_vhost/vhost.h               |  16 ++
 lib/librte_vhost/vhost_user.c          | 313 +++++++++++++++++++++++++
 lib/librte_vhost/vhost_user.h          |  13 +-
 6 files changed, 607 insertions(+), 2 deletions(-)
lib/librte_vhost/rte_vhost.h +105 -0
index 0226b3eff..a17aff876 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
@@ -98,6 +102,41 @@ 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 resubmit_desc {
+	uint16_t index;
+	uint64_t counter;
+};
+
+struct resubmit_info {
+	struct resubmit_desc	*resubmit_list;
+	uint16_t		resubmit_num;
+};
+
+struct rte_vhost_ring_inflight_split {
+	union {
+		struct inflight_info_split *inflight_split;
+		/* TODO */
+	};
+
+	struct resubmit_info *resubmit_inflight_split;
+};
+
 struct rte_vhost_vring {
 	struct vring_desc	*desc;
 	struct vring_avail	*avail;
@@ -603,6 +642,22 @@ 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 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
+ */
+int __rte_experimental
+rte_vhost_get_vhost_ring_inflight_split(int vid, uint16_t vring_idx,
+			      struct rte_vhost_ring_inflight_split *vring);
+
 /**
  * Get guest vring info, including the vring address, vring size, etc.
  *
@@ -631,6 +686,56 @@ int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
  */
 int rte_vhost_vring_call(int vid, uint16_t vring_idx);
 
+/**
+ * set inflight flag for a desc.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_set_inflight_desc_split(int vid, uint16_t vring_idx,
+		uint16_t idx);
+
+/**
+ * clear inflight flag for a desc.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param last_used_idx
+ *  next free used_idx
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_clr_inflight_desc_split(int vid, uint16_t vring_idx,
+		uint16_t last_used_idx, uint16_t idx);
+
+/**
+ * set last inflight io index.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_set_last_inflight_io_split(int vid, uint16_t vring_idx,
+		uint16_t idx);
+
 /**
  * Get vhost RX queue avail count.
  *
lib/librte_vhost/rte_vhost_version.map +4 -0
index 5f1d4a75c..709593701 100644
@@ -87,4 +87,8 @@ EXPERIMENTAL {
 	rte_vdpa_relay_vring_used;
 	rte_vhost_extern_callback_register;
 	rte_vhost_driver_set_protocol_features;
+	rte_vhost_set_inflight_desc_split;
+	rte_vhost_clr_inflight_desc_split;
+	rte_vhost_set_last_inflight_io_split;
+	rte_vhost_get_vhost_vring_with_inflight_split;
 };
lib/librte_vhost/vhost.c +157 -1

183 lines not on this page · raw message

lib/librte_vhost/vhost.h +16 -0
index 884befa85..22925586d 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;
+		/* TODO */
+	};
+	struct resubmit_info *resubmit_inflight_split;
+	uint64_t		global_counter;
+
 	uint16_t		nr_zmbuf;
 	uint16_t		zmbuf_size;
 	uint16_t		last_zmbuf_idx;
@@ -286,6 +294,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 +317,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;
@@ -467,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_split(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 +313 -0

367 lines not on this page · raw message

lib/librte_vhost/vhost_user.h +12 -1
index 2a650fe4b..99a773910 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 {
@@ -112,6 +114,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 */
@@ -131,6 +140,7 @@ typedef struct VhostUserMsg {
 		struct vhost_vring_addr addr;
 		VhostUserMemory memory;
 		VhostUserLog    log;
+		VhostUserInflight inflight;
 		struct vhost_iotlb_msg iotlb;
 		VhostUserCryptoSessionParam crypto_session;
 		VhostUserVringArea area;
@@ -148,6 +158,7 @@ typedef struct VhostUserMsg {
 /* vhost_user.c */
 int vhost_user_msg_handler(int vid, int fd);
 int vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm);
+void *inflight_mem_alloc(const char *name, size_t size, int *fd);
 
 /* socket.c */
 int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
Signature · 1 line
2.17.2
author
#6 lore raw

PATCH v2 1/2 vhost: support inflight share memory protocol feature

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.

Firstly, qemu uses VHOST_USER_GET_INFLIGHT_FD to get the shared buffer from backend. Then qemu should send it back through VHOST_USER_SET_INFLIGHT_FD each time we start vhost-user.

This shared buffer is used to process inflight I/O when backend reconnect.

---
v1 - specify the APIs are split-ring only
v2 - fix APIs and judge split or packed

---
 lib/librte_vhost/rte_vhost.h           | 105 +++++++++
 lib/librte_vhost/rte_vhost_version.map |   4 +
 lib/librte_vhost/vhost.c               | 158 ++++++++++++-
 lib/librte_vhost/vhost.h               |  16 ++
 lib/librte_vhost/vhost_user.c          | 313 +++++++++++++++++++++++++
 lib/librte_vhost/vhost_user.h          |  13 +-
 6 files changed, 607 insertions(+), 2 deletions(-)
lib/librte_vhost/rte_vhost.h +105 -0
index 0226b3eff..a17aff876 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
@@ -98,6 +102,41 @@ 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 resubmit_desc {
+	uint16_t index;
+	uint64_t counter;
+};
+
+struct resubmit_info {
+	struct resubmit_desc	*resubmit_list;
+	uint16_t		resubmit_num;
+};
+
+struct rte_vhost_ring_inflight_split {
+	union {
+		struct inflight_info_split *inflight_split;
+		/* TODO */
+	};
+
+	struct resubmit_info *resubmit_inflight_split;
+};
+
 struct rte_vhost_vring {
 	struct vring_desc	*desc;
 	struct vring_avail	*avail;
@@ -603,6 +642,22 @@ 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 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
+ */
+int __rte_experimental
+rte_vhost_get_vhost_ring_inflight_split(int vid, uint16_t vring_idx,
+			      struct rte_vhost_ring_inflight_split *vring);
+
 /**
  * Get guest vring info, including the vring address, vring size, etc.
  *
@@ -631,6 +686,56 @@ int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
  */
 int rte_vhost_vring_call(int vid, uint16_t vring_idx);
 
+/**
+ * set inflight flag for a desc.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_set_inflight_desc_split(int vid, uint16_t vring_idx,
+		uint16_t idx);
+
+/**
+ * clear inflight flag for a desc.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param last_used_idx
+ *  next free used_idx
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_clr_inflight_desc_split(int vid, uint16_t vring_idx,
+		uint16_t last_used_idx, uint16_t idx);
+
+/**
+ * set last inflight io index.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param vring_idx
+ *  vring index
+ * @param idx
+ *  inflight entry index
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_set_last_inflight_io_split(int vid, uint16_t vring_idx,
+		uint16_t idx);
+
 /**
  * Get vhost RX queue avail count.
  *
lib/librte_vhost/rte_vhost_version.map +4 -0
index 5f1d4a75c..709593701 100644
@@ -87,4 +87,8 @@ EXPERIMENTAL {
 	rte_vdpa_relay_vring_used;
 	rte_vhost_extern_callback_register;
 	rte_vhost_driver_set_protocol_features;
+	rte_vhost_set_inflight_desc_split;
+	rte_vhost_clr_inflight_desc_split;
+	rte_vhost_set_last_inflight_io_split;
+	rte_vhost_get_vhost_vring_with_inflight_split;
 };
lib/librte_vhost/vhost.c +157 -1

183 lines not on this page · raw message

lib/librte_vhost/vhost.h +16 -0
index 884befa85..22925586d 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;
+		/* TODO */
+	};
+	struct resubmit_info *resubmit_inflight_split;
+	uint64_t		global_counter;
+
 	uint16_t		nr_zmbuf;
 	uint16_t		zmbuf_size;
 	uint16_t		last_zmbuf_idx;
@@ -286,6 +294,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 +317,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;
@@ -467,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_split(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 +313 -0

367 lines not on this page · raw message

lib/librte_vhost/vhost_user.h +12 -1
index 2a650fe4b..99a773910 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 {
@@ -112,6 +114,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 */
@@ -131,6 +140,7 @@ typedef struct VhostUserMsg {
 		struct vhost_vring_addr addr;
 		VhostUserMemory memory;
 		VhostUserLog    log;
+		VhostUserInflight inflight;
 		struct vhost_iotlb_msg iotlb;
 		VhostUserCryptoSessionParam crypto_session;
 		VhostUserVringArea area;
@@ -148,6 +158,7 @@ typedef struct VhostUserMsg {
 /* vhost_user.c */
 int vhost_user_msg_handler(int vid, int fd);
 int vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm);
+void *inflight_mem_alloc(const char *name, size_t size, int *fd);
 
 /* socket.c */
 int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
Signature · 1 line
2.17.2