vhost: support inflight share memory protocol feature
A message that is not in the archive (sent off-list or not yet received): 20190917145234.16951
v7 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.
Now It can both support split and packed ring. The example code show how these API work. The test has passed.
How to test the example:
1, Qemu need two patches.
https://patchwork.kernel.org/patch/10766813/
https://patchwork.kernel.org/patch/10861411/(QEMU merged) 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.
Jin Yu (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 the resubmit inflight information
vhost: add the APIs to operate inflight ring
vhost: add APIs for user getting inflight ring
vhost: add vring functions packed ring support
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/rte_vhost_version.map | 9 + lib/librte_vhost/vhost.c | 416 +++++++- lib/librte_vhost/vhost.h | 16 + lib/librte_vhost/vhost_user.c | 470 ++++++++- lib/librte_vhost/vhost_user.h | 12 +- 13 files changed, 3091 insertions(+), 13 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
PATCH v7 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
v7 - updated base on Maxime's comments
--- 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
@@ -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
@@ -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
PATCH v7 2/10 vhost: add packed ring
In reply to Jin YuThis 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
@@ -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
PATCH v7 3/10 vhost: add the inflight structure
In reply to Jin YuThis 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
@@ -102,6 +102,49 @@ struct rte_vhost_memory {struct rte_vhost_mem_region regions[]; }; +struct rte_vhost_inflight_desc_split { +uint8_t inflight; +uint8_t padding[5 ]; +uint16_t next; +uint64_t counter; +}; + +struct rte_vhost_inflight_info_split { +uint64_t features; +uint16_t version; +uint16_t desc_num; +uint16_t last_inflight_io; +uint16_t used_idx; +struct rte_vhost_inflight_desc_split desc[0 ]; +}; + +struct rte_vhost_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 rte_vhost_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 rte_vhost_inflight_desc_packed desc[0 ]; +}; + struct rte_vhost_vring { union { struct vring_desc *desc;
Signature · 1 line
2.17.2
PATCH v7 4/10 vhost: add two new messages to support a shared buffer
In reply to Jin YuThis 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 | 260 +++++++++++++++++++++++++++++++++- lib/librte_vhost/vhost_user.h | 4 +- 3 files changed, 269 insertions(+), 2 deletions(-)
lib/librte_vhost/vhost.h +7 -0
@@ -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 +259 -1
298 lines not on this page · raw message
lib/librte_vhost/vhost_user.h +3 -1
@@ -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
Re: [dpdk-dev] [PATCH v7 04/10] vhost: add two new messages to support a shared buffer
Quoted 55 lines · Jin Yu
This patch introduces two new messages
VHOST_USER_GET_INFLIGHT_FDandVHOST_USER_SET_INFLIGHT_FDto support transferring a shared buffer between qemu and backend.Signed-off-by Lin Li <[email protected]>Signed-off-by Xun Ni <[email protected]>Signed-off-by Yu Zhang <[email protected]>Signed-off-by Jin Yu <[email protected]>--- lib/librte_vhost/vhost.h | 7 + lib/librte_vhost/vhost_user.c | 260 +++++++++++++++++++++++++++++++++- lib/librte_vhost/vhost_user.h | 4 +- 3 files changed, 269 insertions(+), 2 deletions(-)lib/librte_vhost/vhost.h +7
-0@@ -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 +4
-0@@ -37,6 +37,10 @@#ifdef RTE_LIBRTE_VHOST_POSTCOPY #include <linux/userfaultfd.h> #endif +#ifdef F_ADD_SEALS /* if file sealing is supported, so is memfd */ +#include <linux/memfd.h> +#define MEMFD_SUPPORTED +#endif #include <rte_common.h> #include <rte_malloc.h>
lib/librte_vhost/vhost_user.c line 57
Quoted 5 lines
lib/librte_vhost/vhost_user.c +2
-0@@ -49,6 +53,15 @@#define VIRTIO_MIN_MTU 68#define VIRTIO_MAX_MTU 65535 +#define INFLIGHT_ALIGNMENT 64 +#define INFLIGHT_VERSION 0xabcd
Why the version is 0xabcd? Shouldn't it be 1?
https://git.qemu.org/?p=qemu.git;a=blob;f=docs/interop/vhost-user.rst;h=7827b710aa0a223f6f184b229f4b5ced6420b638;hb=HEAD#l551
https://git.qemu.org/?p=qemu.git;a=blob;f=docs/interop/vhost-user.rst;h=7827b710aa0a223f6f184b229f4b5ced6420b638;hb=HEAD#l658
Quoted 27 lines
lib/librte_vhost/vhost_user.c +13
-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 +91,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 +175,21 @@ 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 ; + }
lib/librte_vhost/vhost_user.c vhost_backend_cleanup(struct virtio_net *dev) · line 191
Quoted 10 lines
lib/librte_vhost/vhost_user.c +10
-0+ +if (dev->inflight_info->fd >0 ) { +close (dev->inflight_info->fd); + dev->inflight_info->fd =-1 ; + } + +if (dev->inflight_info) { +free (dev->inflight_info); + dev->inflight_info =NULL ; + }
You should check dev->inflight_info first before dereferencing it.
Quoted 7 lines
lib/librte_vhost/vhost_user.c +1
-0+if (dev->slave_req_fd >=0 ) {close (dev->slave_req_fd); dev->slave_req_fd =-1 ;@@ -1165,6 +1195,233 @@ virtio_is_ready(struct virtio_net *dev)return 1 ; }
lib/librte_vhost/vhost_user.c virtio_is_ready(struct virtio_net *dev) · line 1206
Quoted 10 lines
lib/librte_vhost/vhost_user.c +9
-0+static int +mem_create (const char *name,unsigned int flags) +{ +#ifdef MEMFD_SUPPORTED +return memfd_create (name, flags); +#else +RTE_LOG (ERR ,VHOST_CONFIG , +"doesn't support memfd--name:%s and flag:%x\n" , + name, flags);
You probably don't want to always print an error when memfd isn't available.
Quoted 76 lines
lib/librte_vhost/vhost_user.c +76
-0+return -1 ; +#endif +} + +static void * +inflight_mem_alloc (const char *name,size_t size,int *fd) +{ +void *ptr; +int mfd =-1 ; +char fname[20 ] ="/tmp/memfd-XXXXXX" ; + + *fd =-1 ; + mfd =mem_create (name,CLOEXEC ); +if (mfd !=-1 ) { +if (ftruncate (mfd, size) ==-1 ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"ftruncate fail for alloc inflight buffer\n" ); +close (mfd); +return NULL ; + } + }else { + mfd =mkstemp (fname); +unlink (fname); + +if (mfd ==-1 ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"mkstemp fail for alloc inflight buffer\n" ); +return NULL ; + } + +if (ftruncate (mfd, size) ==-1 ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"ftruncate fail for alloc inflight buffer\n" ); +close (mfd); +return NULL ; + } + } + + ptr =mmap (0 , size,PROT_READ |PROT_WRITE ,MAP_SHARED , mfd,0 ); +if (ptr ==MAP_FAILED ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"mmap fail for alloc inflight buffer\n" ); +close (mfd); +return NULL ; + } + + *fd = mfd; +return ptr; +} + +static uint32_t +get_pervq_shm_size_split (uint16_t queue_size) +{ +return ALIGN_UP (sizeof (struct rte_vhost_inflight_desc_split ) * + queue_size +sizeof (uint64_t ) +sizeof (uint16_t ) *4 , +INFLIGHT_ALIGNMENT ); +} + +static uint32_t +get_pervq_shm_size_packed (uint16_t queue_size) +{ +return ALIGN_UP (sizeof (struct rte_vhost_inflight_desc_packed ) * + queue_size +sizeof (uint64_t ) +sizeof (uint16_t ) *6 + +sizeof (uint8_t ) *9 ,INFLIGHT_ALIGNMENT ); +} + +static int +vhost_user_get_inflight_fd (struct virtio_net **pdev, +VhostUserMsg *msg, + int main_fd __rte_unused) +{ +int fd, i, j; +uint64_t pervq_inflight_size, mmap_size; +void *addr; +uint16_t num_queues, queue_size; +struct virtio_net *dev = *pdev;
lib/librte_vhost/vhost_user.c virtio_is_ready(struct virtio_net *dev) · line 1292
Quoted 10 lines
lib/librte_vhost/vhost_user.c +10
-0+struct rte_vhost_inflight_info_packed *inflight_packed =NULL ; + +if (msg->size !=sizeof (msg->payload.inflight)) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Invalid get_inflight_fd message size is %d" , + msg->size); +return RTE_VHOST_MSG_RESULT_ERR ; + } + + dev->inflight_info =calloc (1 ,sizeof (struct inflight_mem_info ));
You need to check whether dev->inflight_info has been allocated, otherwise memory may leak.
Quoted 104 lines
lib/librte_vhost/vhost_user.c +104
-0+if (!dev->inflight_info) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Failed to alloc dev inflight area" ); +return RTE_VHOST_MSG_RESULT_ERR ; + } + + num_queues = msg->payload.inflight.num_queues; + queue_size = msg->payload.inflight.queue_size; + +RTE_LOG (INFO ,VHOST_CONFIG ,"get_inflight_fd num_queues: %u\n" , + msg->payload.inflight.num_queues); +RTE_LOG (INFO ,VHOST_CONFIG ,"get_inflight_fd queue_size: %u\n" , + msg->payload.inflight.queue_size); + +if (vq_is_packed (dev)) + pervq_inflight_size =get_pervq_shm_size_packed (queue_size); +else + pervq_inflight_size =get_pervq_shm_size_split (queue_size); + + mmap_size = num_queues * pervq_inflight_size; + addr =inflight_mem_alloc ("vhost-inflight" , mmap_size, &fd); +if (!addr) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Failed to alloc vhost inflight area" ); + msg->payload.inflight.mmap_size =0 ; +return RTE_VHOST_MSG_RESULT_ERR ; + } +memset (addr,0 , mmap_size); + + dev->inflight_info->addr = addr; + dev->inflight_info->size = msg->payload.inflight.mmap_size = mmap_size; + dev->inflight_info->fd = msg->fds[0 ] = fd; + msg->payload.inflight.mmap_offset =0 ; + msg->fd_num =1 ; + +if (vq_is_packed (dev)) { +for (i =0 ; i < num_queues; i++) { + inflight_packed = + (struct rte_vhost_inflight_info_packed *)addr; + inflight_packed->used_wrap_counter =1 ; + inflight_packed->old_used_wrap_counter =1 ; +for (j =0 ; j < queue_size; j++) + inflight_packed->desc[j].next = j +1 ; + addr = (void *)((char *)addr + pervq_inflight_size); + } + } + +RTE_LOG (INFO ,VHOST_CONFIG , +"send inflight mmap_size: %" PRIu64"\n" , + msg->payload.inflight.mmap_size); +RTE_LOG (INFO ,VHOST_CONFIG , +"send inflight mmap_offset: %" PRIu64"\n" , + msg->payload.inflight.mmap_offset); +RTE_LOG (INFO ,VHOST_CONFIG , +"send inflight fd: %d\n" , msg->fds[0 ]); + +return RTE_VHOST_MSG_RESULT_REPLY ; +} + +static int +vhost_user_set_inflight_fd (struct virtio_net **pdev,VhostUserMsg *msg, + int main_fd __rte_unused) +{ +int fd; +uint64_t mmap_size, mmap_offset; +uint16_t num_queues, queue_size; +uint32_t pervq_inflight_size; +void *addr; +struct virtio_net *dev = *pdev; + + fd = msg->fds[0 ]; +if (msg->size !=sizeof (msg->payload.inflight) || fd <0 ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Invalid set_inflight_fd message size is %d,fd is %d\n" , + msg->size, fd); +return RTE_VHOST_MSG_RESULT_ERR ; + } + + mmap_size = msg->payload.inflight.mmap_size; + mmap_offset = msg->payload.inflight.mmap_offset; + num_queues = msg->payload.inflight.num_queues; + queue_size = msg->payload.inflight.queue_size; + +if (vq_is_packed (dev)) + pervq_inflight_size =get_pervq_shm_size_packed (queue_size); +else + pervq_inflight_size =get_pervq_shm_size_split (queue_size); + +RTE_LOG (INFO ,VHOST_CONFIG , +"set_inflight_fd mmap_size: %" PRIu64"\n" , mmap_size); +RTE_LOG (INFO ,VHOST_CONFIG , +"set_inflight_fd mmap_offset: %" PRIu64"\n" , mmap_offset); +RTE_LOG (INFO ,VHOST_CONFIG , +"set_inflight_fd num_queues: %u\n" , num_queues); +RTE_LOG (INFO ,VHOST_CONFIG , +"set_inflight_fd queue_size: %u\n" , queue_size); +RTE_LOG (INFO ,VHOST_CONFIG , +"set_inflight_fd fd: %d\n" , fd); +RTE_LOG (INFO ,VHOST_CONFIG , +"set_inflight_fd pervq_inflight_size: %d\n" , + pervq_inflight_size); + +if (!dev->inflight_info) { + dev->inflight_info = calloc(1,
lib/librte_vhost/vhost_user.c virtio_is_ready(struct virtio_net *dev) · line 1406
Quoted 10 lines
lib/librte_vhost/vhost_user.c +10
-0+ sizeof(struct inflight_mem_info)); +if (dev->inflight_info ==NULL ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Failed to alloc dev inflight area" ); +return RTE_VHOST_MSG_RESULT_ERR ; + } + } + +if (dev->inflight_info->addr) +munmap (dev->inflight_info->addr, dev->inflight_info->size);
dev->inflight_info->addr won't be zeroed when below mmap() fails.
Quoted 51 lines
lib/librte_vhost/vhost_user.c +20
-1+ + addr =mmap (0 , mmap_size,PROT_READ |PROT_WRITE ,MAP_SHARED , + fd, mmap_offset); +if (addr ==MAP_FAILED ) { +RTE_LOG (ERR ,VHOST_CONFIG ,"failed to mmap share memory.\n" ); +return RTE_VHOST_MSG_RESULT_ERR ; + } + +if (dev->inflight_info->fd) +close (dev->inflight_info->fd); + + dev->inflight_info->fd = fd; + dev->inflight_info->addr = addr; + dev->inflight_info->size = mmap_size; + +return RTE_VHOST_MSG_RESULT_OK ; +} +static int vhost_user_set_vring_call (struct virtio_net **pdev,struct VhostUserMsg *msg, int main_fd __rte_unused)@@ -1762,9 +2019,10 @@ static vhost_message_handler_t vhost_message_handlers[VHOST_USER_MAX] = { [VHOST_USER_POSTCOPY_ADVISE] = vhost_user_set_postcopy_advise, [VHOST_USER_POSTCOPY_LISTEN] = vhost_user_set_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, }; -/* return bytes# of read on success or negative val on failure. */ static int read_vhost_message (int sockfd,struct VhostUserMsg *msg)lib/librte_vhost/vhost_user.h +3
-1@@ -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
Re: [dpdk-dev] [PATCH v7 04/10] vhost: add two new messages to support a shared buffer
Quoted 73 lines
-----Original Message-----
From: Bie, Tiwei
Sent: Thursday, September 26, 2019 3:39 PM
To: Yu, Jin <[email protected]>
Cc: [email protected]; Liu, Changpeng <[email protected]>; [email protected]; Wang, Zhihong <[email protected]>; Lin Li <[email protected]>; Xun Ni <[email protected]>; Yu Zhang <[email protected]>
Subject: Re: [PATCH v7 04/10] vhost: add two new messages to support a shared bufferQuoted 53 lines · Jin Yu
This patch introduces two new messages
VHOST_USER_GET_INFLIGHT_FDandVHOST_USER_SET_INFLIGHT_FDto support transferring a shared buffer between qemu and backend.Signed-off-by Lin Li <[email protected]>Signed-off-by Xun Ni <[email protected]>Signed-off-by Yu Zhang <[email protected]>Signed-off-by Jin Yu <[email protected]>--- lib/librte_vhost/vhost.h | 7 + lib/librte_vhost/vhost_user.c | 260 +++++++++++++++++++++++++++++++++- lib/librte_vhost/vhost_user.h | 4 +- 3 files changed, 269 insertions(+), 2 deletions(-)lib/librte_vhost/vhost.h index renamed from lib/librte_vhost/vhost.h +0
-0
884befa85..d67ba849a100644lib/librte_vhost/vhost.h +7
-0@@ -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;(quoted diff) +0
-0
b/lib/librte_vhost/vhost_user.cindexc9e29ece8..66582a30f100644lib/librte_vhost/vhost_user.c +2
-0@@ -37,6 +37,10 @@#ifdef RTE_LIBRTE_VHOST_POSTCOPY #include <linux/userfaultfd.h> #endif +#ifdef F_ADD_SEALS /* if file sealing is supported, so is memfd */ +#include <linux/memfd.h> #define MEMFD_SUPPORTED #endif#include <rte_common.h> #include <rte_malloc.h> lib/librte_vhost/vhost_user.c line 57
Quoted 5 lines
lib/librte_vhost/vhost_user.c +2
-0@@ -49,6 +53,15 @@#define VIRTIO_MIN_MTU 68#define VIRTIO_MAX_MTU 65535 +#define INFLIGHT_ALIGNMENT 64 +#define INFLIGHT_VERSION 0xabcdWhy the version is
0xabcd? Shouldn't it be 1?
Quoted 4 lines
https://git.qemu.org/?p=qemu.git;a=blob;f=docs/interop/vhost-
user.rst;h=7827b710aa0a223f6f184b229f4b5ced6420b638;hb=HEAD#l551
https://git.qemu.org/?p=qemu.git;a=blob;f=docs/interop/vhost-
user.rst;h=7827b710aa0a223f6f184b229f4b5ced6420b638;hb=HEAD#l658
Yeah, I didn't fix it. Will fix it in next version.
Quoted 27 lines
lib/librte_vhost/vhost_user.c
Quoted 11 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
+91,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",Quoted 10 lines
lib/librte_vhost/vhost_user.c +2
-1[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 +175,21 @@ vhost_backend_cleanup(struct virtio_net *dev) dev->log_addr =0 ; }
Quoted 16 lines
Quoted 4 lines
lib/librte_vhost/vhost_user.c +4
-0+if (dev->inflight_info->addr) { +munmap (dev->inflight_info->addr, dev->inflight_info->size); + dev->inflight_info->addr =NULL ; + }lib/librte_vhost/vhost_user.c vhost_backend_cleanup(struct virtio_net *dev) · line 191
Quoted 10 lines
lib/librte_vhost/vhost_user.c +10
-0+ +if (dev->inflight_info->fd >0 ) { +close (dev->inflight_info->fd); + dev->inflight_info->fd =-1 ; + } + +if (dev->inflight_info) { +free (dev->inflight_info); + dev->inflight_info =NULL ; + }You should check
dev->inflight_infofirst before dereferencing it.
Got it. Thanks.
Quoted 9 lines
Quoted 9 lines
lib/librte_vhost/vhost_user.c +1
-0+if (dev->slave_req_fd >=0 ) {close (dev->slave_req_fd); dev->slave_req_fd =-1 ;@@ -1165,6 +1195,233 @@ virtio_is_ready(struct virtio_net *dev)return 1 ; }
Quoted 10 lines
lib/librte_vhost/vhost_user.c virtio_is_ready(struct virtio_net *dev) · line 1206
Quoted 8 lines
lib/librte_vhost/vhost_user.c +8
-0+static int +mem_create (const char *name,unsigned int flags) {#ifdef +MEMFD_SUPPORTED +return memfd_create (name, flags); +#else +RTE_LOG (ERR ,VHOST_CONFIG , +"doesn't support memfd--name:%s and flag:%x\n" , + name, flags);You probably don't want to always print an error when memfd isn't available.
I saw below error message from ci/Intel-compilation. ../lib/librte_vhost/vhost_user.c:1202:24: error: unused parameter ‘name’ [-Werror=unused-parameter]
mem_create(const char *name, unsigned int flags)
^~~~
../lib/librte_vhost/vhost_user.c:1202:43: error: unused parameter ‘flags’ [-Werror=unused-parameter]
mem_create(const char *name, unsigned int flags)
That's why I add this print.Should I ignore this?
Thanks.
Quoted 78 lines
Quoted 78 lines
lib/librte_vhost/vhost_user.c +77
-0+return -1 ; +#endif +} + +static void * +inflight_mem_alloc (const char *name,size_t size,int *fd) { +void *ptr; +int mfd =-1 ; +char fname[20 ] ="/tmp/memfd-XXXXXX" ; + + *fd =-1 ; + mfd =mem_create (name,CLOEXEC ); +if (mfd !=-1 ) { +if (ftruncate (mfd, size) ==-1 ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"ftruncate fail for alloc inflight buffer\n" ); +close (mfd); +return NULL ; + } + }else { + mfd =mkstemp (fname); +unlink (fname); + +if (mfd ==-1 ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"mkstemp fail for alloc inflight buffer\n" ); +return NULL ; + } + +if (ftruncate (mfd, size) ==-1 ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"ftruncate fail for alloc inflight buffer\n" ); +close (mfd); +return NULL ; + } + } + + ptr =mmap (0 , size,PROT_READ |PROT_WRITE ,MAP_SHARED , mfd,0 ); +if (ptr ==MAP_FAILED ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"mmap fail for alloc inflight buffer\n" ); +close (mfd); +return NULL ; + } + + *fd = mfd; +return ptr; +} + +static uint32_t +get_pervq_shm_size_split (uint16_t queue_size) { +return ALIGN_UP (sizeof (struct rte_vhost_inflight_desc_split ) * + queue_size +sizeof (uint64_t ) +sizeof (uint16_t ) *4 , +INFLIGHT_ALIGNMENT ); +} + +static uint32_t +get_pervq_shm_size_packed (uint16_t queue_size) { +return ALIGN_UP (sizeof (struct rte_vhost_inflight_desc_packed ) * + queue_size +sizeof (uint64_t ) +sizeof (uint16_t ) *6 + +sizeof (uint8_t ) *9 ,INFLIGHT_ALIGNMENT ); } + +static int +vhost_user_get_inflight_fd (struct virtio_net **pdev, +VhostUserMsg *msg, + int main_fd __rte_unused) +{ +int fd, i, j; +uint64_t pervq_inflight_size, mmap_size; +void *addr; +uint16_t num_queues, queue_size; +struct virtio_net *dev = *pdev; +struct rte_vhost_inflight_info_packed *inflight_packed =NULL ; + +if (msg->size !=sizeof (msg->payload.inflight)) { + RTE_LOG(ERR, VHOST_CONFIG, + "Invalid get_inflight_fd message size is %d",
Quoted 8 lines
lib/librte_vhost/vhost_user.c virtio_is_ready(struct virtio_net *dev) · line 1292
Quoted 5 lines
lib/librte_vhost/vhost_user.c +5
-0+ msg->size); +return RTE_VHOST_MSG_RESULT_ERR ; + } + + dev->inflight_info =calloc (1 ,sizeof (struct inflight_mem_info ));You need to check whether
dev->inflight_infohas been allocated, otherwise memory may leak.
Yeah, Thanks. Will fix it.
Quoted 110 lines
Quoted 22 lines
lib/librte_vhost/vhost_user.c +21
-0+if (!dev->inflight_info) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Failed to alloc dev inflight area" ); +return RTE_VHOST_MSG_RESULT_ERR ; + } + + num_queues = msg->payload.inflight.num_queues; + queue_size = msg->payload.inflight.queue_size; + +RTE_LOG (INFO ,VHOST_CONFIG ,"get_inflight_fd num_queues: %u\n" , + msg->payload.inflight.num_queues); +RTE_LOG (INFO ,VHOST_CONFIG ,"get_inflight_fd queue_size: %u\n" , + msg->payload.inflight.queue_size); + +if (vq_is_packed (dev)) + pervq_inflight_size =get_pervq_shm_size_packed (queue_size); +else + pervq_inflight_size =get_pervq_shm_size_split (queue_size); + + mmap_size = num_queues * pervq_inflight_size; + addr =inflight_mem_alloc ("vhost-inflight" , mmap_size, &fd);lib/librte_vhost/vhost_user.c virtio_is_ready(struct virtio_net *dev)
Quoted 10 lines
lib/librte_vhost/vhost_user.c +10
-0+if (!addr) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Failed to alloc vhost inflight area" ); + msg->payload.inflight.mmap_size =0 ; +return RTE_VHOST_MSG_RESULT_ERR ; + } +memset (addr,0 , mmap_size); + + dev->inflight_info->addr = addr; + dev->inflight_info->size = msg->payload.inflight.mmap_size =
mmap_size;Quoted 77 lines
lib/librte_vhost/vhost_user.c +77
-0+ dev->inflight_info->fd = msg->fds[0 ] = fd; + msg->payload.inflight.mmap_offset =0 ; + msg->fd_num =1 ; + +if (vq_is_packed (dev)) { +for (i =0 ; i < num_queues; i++) { + inflight_packed = + (struct rte_vhost_inflight_info_packed *)addr; + inflight_packed->used_wrap_counter =1 ; + inflight_packed->old_used_wrap_counter =1 ; +for (j =0 ; j < queue_size; j++) + inflight_packed->desc[j].next = j +1 ; + addr = (void *)((char *)addr + pervq_inflight_size); + } + } + +RTE_LOG (INFO ,VHOST_CONFIG , +"send inflight mmap_size: %" PRIu64"\n" , + msg->payload.inflight.mmap_size); +RTE_LOG (INFO ,VHOST_CONFIG , +"send inflight mmap_offset: %" PRIu64"\n" , + msg->payload.inflight.mmap_offset); +RTE_LOG (INFO ,VHOST_CONFIG , +"send inflight fd: %d\n" , msg->fds[0 ]); + +return RTE_VHOST_MSG_RESULT_REPLY ; +} + +static int +vhost_user_set_inflight_fd (struct virtio_net **pdev,VhostUserMsg *msg, + int main_fd __rte_unused) +{ +int fd; +uint64_t mmap_size, mmap_offset; +uint16_t num_queues, queue_size; +uint32_t pervq_inflight_size; +void *addr; +struct virtio_net *dev = *pdev; + + fd = msg->fds[0 ]; +if (msg->size !=sizeof (msg->payload.inflight) || fd <0 ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Invalid set_inflight_fd message size is %d,fd is %d\n" , + msg->size, fd); +return RTE_VHOST_MSG_RESULT_ERR ; + } + + mmap_size = msg->payload.inflight.mmap_size; + mmap_offset = msg->payload.inflight.mmap_offset; + num_queues = msg->payload.inflight.num_queues; + queue_size = msg->payload.inflight.queue_size; + +if (vq_is_packed (dev)) + pervq_inflight_size =get_pervq_shm_size_packed (queue_size); +else + pervq_inflight_size =get_pervq_shm_size_split (queue_size); + +RTE_LOG (INFO ,VHOST_CONFIG , +"set_inflight_fd mmap_size: %" PRIu64"\n" , mmap_size); +RTE_LOG (INFO ,VHOST_CONFIG , +"set_inflight_fd mmap_offset: %" PRIu64"\n" , mmap_offset); +RTE_LOG (INFO ,VHOST_CONFIG , +"set_inflight_fd num_queues: %u\n" , num_queues); +RTE_LOG (INFO ,VHOST_CONFIG , +"set_inflight_fd queue_size: %u\n" , queue_size); +RTE_LOG (INFO ,VHOST_CONFIG , +"set_inflight_fd fd: %d\n" , fd); +RTE_LOG (INFO ,VHOST_CONFIG , +"set_inflight_fd pervq_inflight_size: %d\n" , + pervq_inflight_size); + +if (!dev->inflight_info) { + dev->inflight_info =calloc (1 , +sizeof (struct inflight_mem_info )); +if (dev->inflight_info ==NULL ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Failed to alloc dev inflight area" );
Quoted 8 lines
lib/librte_vhost/vhost_user.c virtio_is_ready(struct virtio_net *dev) · line 1406
Quoted 6 lines
lib/librte_vhost/vhost_user.c +6
-0+return RTE_VHOST_MSG_RESULT_ERR ; + } + } + +if (dev->inflight_info->addr) +munmap (dev->inflight_info->addr, dev->inflight_info->size);
dev->inflight_info->addrwon't be zeroed when belowmmap()fails.
I think it should be zero when below mmap() fails as this function would return directly, so The dev->inflight_info->addr would not been set.
Quoted 54 lines
lib/librte_vhost/vhost_user.c virtio_is_ready(struct virtio_net *dev)
Quoted 6 lines
lib/librte_vhost/vhost_user.c +5
-0+ + addr =mmap (0 , mmap_size,PROT_READ |PROT_WRITE ,MAP_SHARED , + fd, mmap_offset); +if (addr ==MAP_FAILED ) { + RTE_LOG(ERR, VHOST_CONFIG, "failed to mmap sharememory.\n");
Quoted 5 lines
lib/librte_vhost/vhost_user.c +5
-0+return RTE_VHOST_MSG_RESULT_ERR ; + } + +if (dev->inflight_info->fd) +close (dev->inflight_info->fd);lib/librte_vhost/vhost_user.c virtio_is_ready(struct virtio_net *dev)
Quoted 10 lines
lib/librte_vhost/vhost_user.c +8
-0+ + dev->inflight_info->fd = fd; + dev->inflight_info->addr = addr; + dev->inflight_info->size = mmap_size; + +return RTE_VHOST_MSG_RESULT_OK ; +} +static int vhost_user_set_vring_call(struct virtio_net **pdev, struct VhostUserMsg*msg,
lib/librte_vhost/vhost_user.c static vhost_message_handler_t
Quoted 2 lines
lib/librte_vhost/vhost_user.c +0
-0int main_fd __rte_unused)@@ -1762,9 +2019,10 @@ static vhost_message_handler_tvhost_message_handlers[VHOST_USER_MAX] = {
Quoted 28 lines
lib/librte_vhost/vhost_user.c +2
-1[VHOST_USER_POSTCOPY_ADVISE] = vhost_user_set_postcopy_advise, [VHOST_USER_POSTCOPY_LISTEN] = vhost_user_set_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, }; -/* return bytes# of read on success or negative val on failure. */ static int read_vhost_message (int sockfd,struct VhostUserMsg *msg)(quoted diff) +0
-0
b/lib/librte_vhost/vhost_user.hindex17a1d7bca..6563f7315100644lib/librte_vhost/vhost_user.h +3
-2@@ -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 { --2.17.2
Re: [dpdk-dev] [PATCH v7 04/10] vhost: add two new messages to support a shared buffer
Quoted 11 lines · Jin
Quoted 11 lines
lib/librte_vhost/vhost_user.c virtio_is_ready(struct virtio_net *dev) · line 1206
Quoted 9 lines
lib/librte_vhost/vhost_user.c +8
-0+static int +mem_create (const char *name,unsigned int flags) {#ifdef +MEMFD_SUPPORTED +return memfd_create (name, flags); +#else +RTE_LOG (ERR ,VHOST_CONFIG , +"doesn't support memfd--name:%s and flag:%x\n" , + name, flags);You probably don't want to always print an error when memfd isn't available.
Quoted 8 lines
I saw below error message from ci/Intel-compilation.
../lib/librte_vhost/vhost_user.c:1202:24: error: unused parameter ‘name’ [-Werror=unused-parameter]
mem_create(const char *name, unsigned int flags)^~~~
../lib/librte_vhost/vhost_user.c:1202:43: error: unused parameter ‘flags’ [-Werror=unused-parameter]
mem_create(const char *name, unsigned int flags)That's why I add this print.Should I ignore this?
Looks better to do it like this (compile test only):
static void *inflight_mem_alloc(const char *name, size_t size, int *fd)
{
char fname[20] = "/tmp/memfd-XXXXXX";
int mfd = -1;
void *addr;#ifdef MEMFD_SUPPORTED
mfd = memfd_create(name, MFD_CLOEXEC);
#else
RTE_SET_USED(name);
#endif
if (mfd == -1) {
mfd = mkstemp(fname);
if (mfd == -1) {
RTE_LOG(ERR, VHOST_CONFIG,
"failed to create memory file for inflight buffer\n");
return NULL;
}
unlink(fname);
}
if (ftruncate(mfd, size) == -1) {
RTE_LOG(ERR, VHOST_CONFIG,
"failed to truncate memory file for inflight buffer\n");
close(mfd);
return NULL;
}
addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, mfd, 0);
if (addr == MAP_FAILED) {
RTE_LOG(ERR, VHOST_CONFIG,
"failed to map memory file for inflight buffer\n");
close(mfd);
return NULL;
}
*fd = mfd;
return addr;
}And you don't need to define CLOEXEC by yourself.
Quoted 51 lines
Thanks.
Quoted 49 lines
Quoted 49 lines
lib/librte_vhost/vhost_user.c +48
-0+return -1 ; +#endif +} + +static void * +inflight_mem_alloc (const char *name,size_t size,int *fd) { +void *ptr; +int mfd =-1 ; +char fname[20 ] ="/tmp/memfd-XXXXXX" ; + + *fd =-1 ; + mfd =mem_create (name,CLOEXEC ); +if (mfd !=-1 ) { +if (ftruncate (mfd, size) ==-1 ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"ftruncate fail for alloc inflight buffer\n" ); +close (mfd); +return NULL ; + } + }else { + mfd =mkstemp (fname); +unlink (fname); + +if (mfd ==-1 ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"mkstemp fail for alloc inflight buffer\n" ); +return NULL ; + } + +if (ftruncate (mfd, size) ==-1 ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"ftruncate fail for alloc inflight buffer\n" ); +close (mfd); +return NULL ; + } + } + + ptr =mmap (0 , size,PROT_READ |PROT_WRITE ,MAP_SHARED , mfd,0 ); +if (ptr ==MAP_FAILED ) { +RTE_LOG (ERR ,VHOST_CONFIG , +"mmap fail for alloc inflight buffer\n" ); +close (mfd); +return NULL ; + } + + *fd = mfd; +return ptr; +}
PATCH v7 5/10 vhost: checkout the resubmit inflight information
In reply to Jin YuThis 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 | 212 +++++++++++++++++++++++++++++++++- 4 files changed, 267 insertions(+), 2 deletions(-)
lib/librte_vhost/rte_vhost.h +19 -0
@@ -145,6 +145,25 @@ struct rte_vhost_inflight_info_packed {struct rte_vhost_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 rte_vhost_inflight_info_split *inflight_split; +struct rte_vhost_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
@@ -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
@@ -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 rte_vhost_inflight_info_split *inflight_split; +struct rte_vhost_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 +211 -1
246 lines not on this page · raw message
Signature · 1 line
2.17.2
Re: [dpdk-dev] [PATCH v7 05/10] vhost: checkout the resubmit inflight information
Quoted 4 lines · Jin Yu
lib/librte_vhost/vhost_user.c +0
-0@@ -1458,6 +1472,188 @@ static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused,return RTE_VHOST_MSG_RESULT_OK ; }
lib/librte_vhost/vhost_user.c static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused, · line 1484
Quoted 10 lines
lib/librte_vhost/vhost_user.c +10
-0+static int +resubmit_desc_compare (const void *a,const void *b) +{ +const struct rte_vhost_resubmit_desc *desc0 = + (const struct rte_vhost_resubmit_desc *)a; +const struct rte_vhost_resubmit_desc *desc1 = + (const struct rte_vhost_resubmit_desc *)b; + +if (desc1->counter > desc0->counter && + (desc1->counter - desc0->counter) <VIRTQUEUE_MAX_SIZE *2 )
Why is this hardcoded to 1024 * 2 here?
Quoted 19 lines
lib/librte_vhost/vhost_user.c +19
-0+return 1 ; + +return -1 ; +} + +static int +vhost_check_queue_inflights_split (struct virtio_net *dev, +struct vhost_virtqueue *vq) +{ +uint16_t i =0 ; +uint16_t resubmit_num =0 , last_io, num; +struct vring_used *used = vq->used; +struct rte_vhost_resubmit_info *resubmit =NULL ; +struct rte_vhost_inflight_info_split *inflight_split; + +if (!(dev->protocol_features & + (1ULL <<VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD ))) +return RTE_VHOST_MSG_RESULT_OK ; +
lib/librte_vhost/vhost_user.c static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused, · line 1513
Quoted 10 lines
lib/librte_vhost/vhost_user.c +10
-0+if ((!vq->inflight_split)) +return RTE_VHOST_MSG_RESULT_ERR ; + +if (!vq->inflight_split->version) { + vq->inflight_split->version =INFLIGHT_VERSION ; +return RTE_VHOST_MSG_RESULT_OK ; + } + + inflight_split = vq->inflight_split; + vq->resubmit_inflight =NULL ;
This is invoked in vhost message handler, you need to check whether it has been allocated first.
Quoted 68 lines
lib/librte_vhost/vhost_user.c +68
-0+ vq->global_counter =0 ; + last_io = inflight_split->last_inflight_io; + +if (inflight_split->used_idx != used->idx) { + inflight_split->desc[last_io].inflight =0 ; +rte_compiler_barrier (); + inflight_split->used_idx = used->idx; + } + +for (i =0 ; i < inflight_split->desc_num; i++) { +if (inflight_split->desc[i].inflight ==1 ) + resubmit_num++; + } + + vq->last_avail_idx += resubmit_num; + +if (resubmit_num) { + resubmit =calloc (1 ,sizeof (struct rte_vhost_resubmit_info )); +if (!resubmit) { +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) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Failed to allocate memory for inflight desc.\n" ); +return RTE_VHOST_MSG_RESULT_ERR ; + } + + num =0 ; +for (i =0 ; i < vq->inflight_split->desc_num; i++) { +if (vq->inflight_split->desc[i].inflight ==1 ) { + resubmit->resubmit_list[num].index = i; + resubmit->resubmit_list[num].counter = + inflight_split->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 ; +} + +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 rte_vhost_inflight_info_packed *inflight_packed; + +if (!(dev->protocol_features & + (1ULL <<VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD ))) +return RTE_VHOST_MSG_RESULT_OK ; +
lib/librte_vhost/vhost_user.c static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused, · line 1591
Quoted 10 lines
lib/librte_vhost/vhost_user.c +10
-0+if ((!vq->inflight_packed)) +return RTE_VHOST_MSG_RESULT_ERR ; + +if (!vq->inflight_packed->version) { + vq->inflight_packed->version =INFLIGHT_VERSION ; +return RTE_VHOST_MSG_RESULT_OK ; + } + + inflight_packed = vq->inflight_packed; + vq->resubmit_inflight =NULL ;
Ditto.
Quoted 92 lines
lib/librte_vhost/vhost_user.c +79
-0+ 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 ; +} +static int vhost_user_set_vring_kick (struct virtio_net **pdev,struct VhostUserMsg *msg, int main_fd __rte_unused)@@ -1499,6 +1695,20 @@ vhost_user_set_vring_kick(struct virtio_net **pdev, struct VhostUserMsg *msg,close (vq->kickfd); vq->kickfd = file.fd; +if (vq_is_packed (dev)) { +if (vhost_check_queue_inflights_packed (dev, vq)) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Failed to inflights for vq: %d\n" , file.index); +return RTE_VHOST_MSG_RESULT_ERR ; + } + }else { +if (vhost_check_queue_inflights_split (dev, vq)) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Failed to inflights for vq: %d\n" , file.index); +return RTE_VHOST_MSG_RESULT_ERR ; + } + } +return RTE_VHOST_MSG_RESULT_OK ; }Signature · 1 line
2.17.2
Re: [dpdk-dev] [PATCH v7 05/10] vhost: checkout the resubmit inflight information
Quoted 16 lines
-----Original Message-----
From: Bie, Tiwei
Sent: Thursday, September 26, 2019 4:05 PM
To: Yu, Jin <[email protected]>
Cc: [email protected]; Liu, Changpeng <[email protected]>; [email protected]; Wang, Zhihong <[email protected]>; Lin Li <[email protected]>; Xun Ni <[email protected]>; Yu Zhang <[email protected]>
Subject: Re: [PATCH v7 05/10] vhost: checkout the resubmit inflight informationReview static int vhost_user_set_vring_err(struct
Quoted 1 line · Jin Yu
(quoted diff) +0
-0@@ -1458,6 +1472,188 @@ static int vhost_user_set_vring_err(struct
virtio_net**pdev__rte_unused,Quoted 3 lines
lib/librte_vhost/vhost_user.c +0
-0return RTE_VHOST_MSG_RESULT_OK ; }
Quoted 11 lines
lib/librte_vhost/vhost_user.c static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused, · line 1484
Quoted 9 lines
lib/librte_vhost/vhost_user.c +9
-0+static int +resubmit_desc_compare (const void *a,const void *b) { +const struct rte_vhost_resubmit_desc *desc0 = + (const struct rte_vhost_resubmit_desc *)a; +const struct rte_vhost_resubmit_desc *desc1 = + (const struct rte_vhost_resubmit_desc *)b; + +if (desc1->counter > desc0->counter && + (desc1->counter - desc0->counter) <VIRTQUEUE_MAX_SIZE *2 )Why is this hardcoded to 1024 * 2 here?
I will check this. Thanks.
Quoted 25 lines
Quoted 25 lines
lib/librte_vhost/vhost_user.c +24
-0+return 1 ; + +return -1 ; +} + +static int +vhost_check_queue_inflights_split (struct virtio_net *dev, +struct vhost_virtqueue *vq) +{ +uint16_t i =0 ; +uint16_t resubmit_num =0 , last_io, num; +struct vring_used *used = vq->used; +struct rte_vhost_resubmit_info *resubmit =NULL ; +struct rte_vhost_inflight_info_split *inflight_split; + +if (!(dev->protocol_features & + (1ULL <<VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD ))) +return RTE_VHOST_MSG_RESULT_OK ; + +if ((!vq->inflight_split)) +return RTE_VHOST_MSG_RESULT_ERR ; + +if (!vq->inflight_split->version) { + vq->inflight_split->version =INFLIGHT_VERSION ;
Quoted 8 lines
lib/librte_vhost/vhost_user.c static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused, · line 1513
Quoted 5 lines
lib/librte_vhost/vhost_user.c +5
-0+return RTE_VHOST_MSG_RESULT_OK ; + } + + inflight_split = vq->inflight_split; + vq->resubmit_inflight =NULL ;This is invoked in vhost message handler, you need to check whether it has been allocated first.
Got it, Thanks.
Quoted 180 lines
Quoted 71 lines
lib/librte_vhost/vhost_user.c +68
-0+ vq->global_counter =0 ; + last_io = inflight_split->last_inflight_io; + +if (inflight_split->used_idx != used->idx) { + inflight_split->desc[last_io].inflight =0 ; +rte_compiler_barrier (); + inflight_split->used_idx = used->idx; + } + +for (i =0 ; i < inflight_split->desc_num; i++) { +if (inflight_split->desc[i].inflight ==1 ) + resubmit_num++; + } + + vq->last_avail_idx += resubmit_num; + +if (resubmit_num) { + resubmit =calloc (1 ,sizeof (struct rte_vhost_resubmit_info )); +if (!resubmit) { +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) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Failed to allocate memory for inflight desc.\n" ); +return RTE_VHOST_MSG_RESULT_ERR ; + } + + num =0 ; +for (i =0 ; i < vq->inflight_split->desc_num; i++) { +if (vq->inflight_split->desc[i].inflight ==1 ) { + resubmit->resubmit_list[num].index = i; + resubmit->resubmit_list[num].counter = + inflight_split->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 ; +} + +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 rte_vhost_inflight_info_packed *inflight_packed; + +if (!(dev->protocol_features & + (1ULL <<VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD ))) +return RTE_VHOST_MSG_RESULT_OK ; +lib/librte_vhost/vhost_user.c static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused, · line 1591
Quoted 10 lines
lib/librte_vhost/vhost_user.c +10
-0+if ((!vq->inflight_packed)) +return RTE_VHOST_MSG_RESULT_ERR ; + +if (!vq->inflight_packed->version) { + vq->inflight_packed->version =INFLIGHT_VERSION ; +return RTE_VHOST_MSG_RESULT_OK ; + } + + inflight_packed = vq->inflight_packed; + vq->resubmit_inflight =NULL ;Ditto.
Quoted 58 lines
lib/librte_vhost/vhost_user.c +57
-0+ 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);lib/librte_vhost/vhost_user.c static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused,
Quoted 10 lines
lib/librte_vhost/vhost_user.c +8
-0+ + vq->global_counter = resubmit->resubmit_list[0 ].counter +1 ; + vq->resubmit_inflight = resubmit; + } + +return RTE_VHOST_MSG_RESULT_OK ; +} +static int vhost_user_set_vring_kick(struct virtio_net **pdev, struct VhostUserMsg*msg,
Review vhost_user_set_vring_kick(struct virtio_net
Quoted 2 lines
(quoted diff) +0
-0int main_fd __rte_unused)@@ -1499,6 +1695,20 @@ vhost_user_set_vring_kick(struct virtio_net**pdev, struct VhostUserMsg *msg,
Quoted 23 lines
lib/librte_vhost/vhost_user.c +14
-1close (vq->kickfd); vq->kickfd = file.fd; +if (vq_is_packed (dev)) { +if (vhost_check_queue_inflights_packed (dev, vq)) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Failed to inflights for vq: %d\n" , file.index); +return RTE_VHOST_MSG_RESULT_ERR ; + } + }else { +if (vhost_check_queue_inflights_split (dev, vq)) { +RTE_LOG (ERR ,VHOST_CONFIG , +"Failed to inflights for vq: %d\n" , file.index); +return RTE_VHOST_MSG_RESULT_ERR ; + } + } +return RTE_VHOST_MSG_RESULT_OK ; } --2.17.2
PATCH v7 6/10 vhost: add the APIs to operate inflight ring
In reply to Jin YuThis 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/rte_vhost_version.map | 6 + lib/librte_vhost/vhost.c | 272 +++++++++++++++++++++++++ 3 files changed, 394 insertions(+)
lib/librte_vhost/rte_vhost.h +116 -0
@@ -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/rte_vhost_version.map +6 -0
@@ -87,4 +87,10 @@ 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_set_inflight_desc_packed; + rte_vhost_set_last_inflight_io_split; + rte_vhost_set_last_inflight_io_packed; + rte_vhost_clr_inflight_desc_split; + rte_vhost_clr_inflight_desc_packed; };
lib/librte_vhost/vhost.c +272 -0
278 lines not on this page · raw message
Signature · 1 line
2.17.2
PATCH v7 7/10 vhost: add APIs for user getting inflight ring
In reply to Jin YuThis 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/rte_vhost_version.map | 2 + lib/librte_vhost/vhost.c | 59 ++++++++++++++++++++++++++ 3 files changed, 101 insertions(+)
lib/librte_vhost/rte_vhost.h +40 -0
@@ -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/rte_vhost_version.map +2 -0
@@ -93,4 +93,6 @@ EXPERIMENTAL { rte_vhost_set_last_inflight_io_packed; rte_vhost_clr_inflight_desc_split; rte_vhost_clr_inflight_desc_packed; + rte_vhost_get_vhost_ring_inflight; + rte_vhost_get_vring_base_from_inflight; };
lib/librte_vhost/vhost.c +59 -0
71 lines not on this page · raw message
Signature · 1 line
2.17.2
PATCH v7 8/10 vhost: add vring functions packed ring support
In reply to Jin YuThis patch add packed ring support in two APIs so user can get the packed ring`.
--- lib/librte_vhost/vhost.c | 68 +++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 19 deletions(-)
lib/librte_vhost/vhost.c +49 -19
@@ -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;
@@ -1273,13 +1279,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 ; }
@@ -1308,20 +1352,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
PATCH v7 9/10 vhost: add an API for judging vq format
In reply to Jin YuThis patch introduces an API for getting virtqueue format.
--- lib/librte_vhost/rte_vhost.h | 13 +++++++++++++ lib/librte_vhost/rte_vhost_version.map | 1 + lib/librte_vhost/vhost.c | 12 ++++++++++++ 3 files changed, 26 insertions(+)
lib/librte_vhost/rte_vhost.h +13 -0
@@ -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/rte_vhost_version.map +1 -0
@@ -95,4 +95,5 @@ EXPERIMENTAL { rte_vhost_clr_inflight_desc_packed; rte_vhost_get_vhost_ring_inflight; rte_vhost_get_vring_base_from_inflight; + rte_vhost_vq_is_packed; };
lib/librte_vhost/vhost.c +12 -0
@@ -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
PATCH v7 10/10 vhost: add vhost-user-blk example which support inflight
In reply to Jin YuA 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
@@ -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
@@ -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
Re: [dpdk-dev] [PATCH v7 10/10] vhost: add vhost-user-blk example which support inflight
Quoted 2 lines · Jin Yu
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
s/It/it/
s/there/these/
Quoted 7 lines
APIs work to support inflight feature.
Signed-off-by Jin Yu <[email protected]>---
V1 - add the case.
V2 - add therte_vhostprefix.
V3 - add packed ring support
Quoted 9 lines
--- 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(+)
I met some build issues when trying this example.
examples/vhost_blk/vhost_blk.c: In function ‘descriptor_get_next_packed’:examples/vhost_blk/vhost_blk.c:71:21: error: invalid use of undefined type ‘struct vring_packed_desc’
if (vq->desc_packed[*idx % vq->size].flags & VIRTQ_DESC_F_NEXT) {
^
examples/vhost_blk/vhost_blk.c:71:21: error: dereferencing pointer to incomplete type ‘struct vring_packed_desc’
examples/vhost_blk/vhost_blk.c:73:26: error: invalid use of undefined type ‘struct vring_packed_desc’
return &vq->desc_packed[*idx % vq->size];
^examples/vhost_blk/vhost_blk.c: In function ‘inflight_submit_completion_packed’:examples/vhost_blk/vhost_blk.c:165:2: warning: ‘rte_vhost_set_last_inflight_io_packed’ is deprecated: Symbol is not yet part of stable ABI [-Wdeprecated-declarations]
ret = rte_vhost_set_last_inflight_io_packed(ctrlr->bdev->vid, q_idx,
^~~
In file included from examples/vhost_blk/vhost_blk.c:17:0:x86_64-native-linuxapp-gcc/include/rte_vhost.h:810:1: note: declared here
rte_vhost_set_last_inflight_io_packed(int vid,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^
...
Re: [dpdk-dev] [PATCH v7 10/10] vhost: add vhost-user-blk example which support inflight
Quoted 9 lines
-----Original Message-----
From: Bie, Tiwei
Sent: Wednesday, September 25, 2019 10:46 PM
To: Yu, Jin <[email protected]>
Cc: [email protected]; Liu, Changpeng <[email protected]>; [email protected]; Wang, Zhihong <[email protected]>
Subject: Re: [PATCH v7 10/10] vhost: add vhost-user-blk example which support inflight
Quoted 6 lines
Quoted 2 lines · Jin Yu
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
s/It/it/
s/there/these/
Got it. Thanks.
Quoted 23 lines
Quoted 8 lines
APIs work to support inflight feature.
Signed-off-by Jin Yu <[email protected]>---
V1 - add the case.
V2 - add therte_vhostprefix.
V3 - add packed ring supportQuoted 9 lines
--- 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(+)I met some build issues when trying this example.
examples/vhost_blk/vhost_blk.c: In function ‘descriptor_get_next_packed’:examples/vhost_blk/vhost_blk.c:71:21: error: invalid use of undefined type ‘struct vring_packed_desc’
Quoted 7 lines
if (vq->desc_packed[*idx % vq->size].flags & VIRTQ_DESC_F_NEXT) { ^
examples/vhost_blk/vhost_blk.c:71:21: error: dereferencing pointer to incomplete type ‘struct vring_packed_desc’examples/vhost_blk/vhost_blk.c:73:26: error: invalid use of undefined type ‘struct vring_packed_desc’
return &vq->desc_packed[*idx %vq->size];
The new version of virtio_ring.h have defined the vring_packed_desc. For the compatibility, I will add the definition in the rte_vhost.h. Thanks.
Quoted 6 lines
^
examples/vhost_blk/vhost_blk.c: In function ‘inflight_submit_completion_packed’:examples/vhost_blk/vhost_blk.c:165:2: warning:
‘rte_vhost_set_last_inflight_io_packed’ is deprecated: Symbol is not yet part of stable ABI [-Wdeprecated-declarations]
Should I ignore this warning? I'm not sure about this. The reason is the _rte_experiment keyword? Thanks.
Quoted 8 lines
ret = rte_vhost_set_last_inflight_io_packed(ctrlr->bdev->vid,
q_idx, ^~~
In file included fromexamples/vhost_blk/vhost_blk.c:17:0:x86_64-native-linuxapp-gcc/include/rte_vhost.h:810:1: note: declared here rte_vhost_set_last_inflight_io_packed(int vid, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^...
Re: [dpdk-dev] [PATCH v7 10/10] vhost: add vhost-user-blk example which support inflight
Quoted 48 lines · Jin
Quoted 9 lines
-----Original Message-----
From: Bie, Tiwei
Sent: Wednesday, September 25, 2019 10:46 PM
To: Yu, Jin <[email protected]>
Cc: [email protected]; Liu, Changpeng <[email protected]>; [email protected]; Wang, Zhihong <[email protected]>
Subject: Re: [PATCH v7 10/10] vhost: add vhost-user-blk example which support inflightQuoted 6 lines
Quoted 2 lines · Jin Yu
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
s/It/it/
s/there/these/Got it. Thanks.
Quoted 23 lines
Quoted 8 lines
APIs work to support inflight feature.
Signed-off-by Jin Yu <[email protected]>---
V1 - add the case.
V2 - add therte_vhostprefix.
V3 - add packed ring supportQuoted 9 lines
--- 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(+)I met some build issues when trying this example.
examples/vhost_blk/vhost_blk.c: In function ‘descriptor_get_next_packed’:examples/vhost_blk/vhost_blk.c:71:21: error: invalid use of undefined type ‘struct vring_packed_desc’Quoted 7 lines
if (vq->desc_packed[*idx % vq->size].flags & VIRTQ_DESC_F_NEXT) { ^
examples/vhost_blk/vhost_blk.c:71:21: error: dereferencing pointer to incomplete type ‘struct vring_packed_desc’examples/vhost_blk/vhost_blk.c:73:26: error: invalid use of undefined type ‘struct vring_packed_desc’
return &vq->desc_packed[*idx %vq->size];
Quoted 2 lines
The new version of
virtio_ring.hhave defined thevring_packed_desc. For the compatibility, I will add the definition in therte_vhost.h.
No. They should be added in this example instead of the vhost API.
Quoted 11 lines
Thanks.
Quoted 6 lines
^
examples/vhost_blk/vhost_blk.c: In function ‘inflight_submit_completion_packed’:examples/vhost_blk/vhost_blk.c:165:2: warning:
‘rte_vhost_set_last_inflight_io_packed’ is deprecated: Symbol is not yet part of stable ABI [-Wdeprecated-declarations]Should I ignore this warning? I'm not sure about this. The reason is the
_rte_experimentkeyword?
You need something like this:
https://github.com/DPDK/dpdk/blob/bd253daa7717835f88bbc58b09a94d0060380396/examples/vhost/Makefile#L29
https://github.com/DPDK/dpdk/blob/bd253daa7717835f88bbc58b09a94d0060380396/examples/vhost/meson.build#L13
Quoted 9 lines
Thanks.
Quoted 8 lines
ret = rte_vhost_set_last_inflight_io_packed(ctrlr->bdev->vid,
q_idx, ^~~
In file included fromexamples/vhost_blk/vhost_blk.c:17:0:x86_64-native-linuxapp-gcc/include/rte_vhost.h:810:1: note: declared here rte_vhost_set_last_inflight_io_packed(int vid, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^...
Quoted 2 lines
[PATCH v7 00/10] vhost: support inflight share memory protocol feature
This should be v8. Please increase the version number when sending a new series.
Thanks,
Tiwei
Quoted 68 lines · Jin Yu
This patches introduces two new messages
VHOST_USER_GET_INFLIGHT_FDandVHOST_USER_SET_INFLIGHT_FDto support transferring a shared buffer between qemu and backend.
Now It can both support split and packed ring. The example code show how these API work. The test has passed.How to test the example:
1, Qemu need two patches.
https://patchwork.kernel.org/patch/10766813/
https://patchwork.kernel.org/patch/10861411/(QEMU merged) 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 invhost_dev_get_inflightint 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.Jin Yu (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 the resubmit inflight information
vhost: add the APIs to operate inflight ring
vhost: add APIs for user getting inflight ring
vhost: add vring functions packed ring support
vhost: add an API for judging vq format
vhost: add vhost-user-blk example which support inflightexamples/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/rte_vhost_version.map | 9 + lib/librte_vhost/vhost.c | 416 +++++++- lib/librte_vhost/vhost.h | 16 + lib/librte_vhost/vhost_user.c | 470 ++++++++- lib/librte_vhost/vhost_user.h | 12 +- 13 files changed, 3091 insertions(+), 13 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.cSignature · 1 line
2.17.2
Quoted 10 lines
-----Original Message-----
From: Bie, Tiwei
Sent: Wednesday, September 25, 2019 10:26 PM
To: Yu, Jin <[email protected]>
Cc: [email protected]; Liu, Changpeng <[email protected]>; [email protected]; Wang, Zhihong <[email protected]>
Subject: Re: [PATCH v7 00/10] vhost: support inflight share memory protocol feature
Quoted 3 lines
Quoted 1 line
[PATCH v7 00/10] vhost: support inflight share memory protocol feature
This should be v8. Please increase the version number when sending a new series.
I thought it's a small fix. I will fix it. Thanks.
Quoted 75 lines
Thanks,
TiweiQuoted 70 lines · Jin Yu
This patches introduces two new messages
VHOST_USER_GET_INFLIGHT_FDandVHOST_USER_SET_INFLIGHT_FDto support transferring a shared buffer between qemu and backend.
Now It can both support split and packed ring. The example code show how these API work. The test has passed.How to test the example:
1, Qemu need two patches.
https://patchwork.kernel.org/patch/10766813/
https://patchwork.kernel.org/patch/10861411/(QEMU merged) 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 invhost_dev_get_inflightint 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\ -devicevhost-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.Jin Yu (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 the resubmit inflight information
vhost: add the APIs to operate inflight ring
vhost: add APIs for user getting inflight ring
vhost: add vring functions packed ring support
vhost: add an API for judging vq format
vhost: add vhost-user-blk example which support inflightexamples/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/rte_vhost_version.map | 9 + lib/librte_vhost/vhost.c | 416 +++++++- lib/librte_vhost/vhost.h | 16 + lib/librte_vhost/vhost_user.c | 470 ++++++++- lib/librte_vhost/vhost_user.h | 12 +- 13 files changed, 3091 insertions(+), 13 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--
2.17.2