: Alibaba patches for SPDK summit discussion
Ming Lin
cover : Alibaba patches for SPDK summit discussion
From: Ming Lin <ming.lin(a)alibaba-inc.com>
Hi,
Here are some of the patches we'd like to discuss at the comming SPDK summit. Patches were based on SPDK v17.10 and can't be applied cleanly on upstream SPDK. But it should be OK for discussion.
[RFC PATCH 1/4] changed vhost to support multi-process access same target [RFC PATCH 2/4] support virtio-scsi to reconnect to vhost process when vhost restart [RFC PATCH 3/4] add ScanTarget to optimize spdk app start time
[RFC PATCH 4/4] rpc: add blocked version of rpc server with epoll
Thanks,
Ming
Ming Lin
RFC PATCH 1/4 changed vhost to support multi-process access same target
From: Sheng Qiu <sheng.qiu(a)alibaba-inc.com>
--- lib/vhost/vhost.c | 69 +++++++- lib/vhost/vhost_internal.h | 7 + lib/vhost/vhost_scsi.c | 411 +++++++++++++++++++++++++++------------------ 3 files changed, 316 insertions(+), 171 deletions(-)
lib/vhost/vhost.c +61 -8
@@ -456,6 +456,29 @@ spdk_vhost_dev_find_id(const char *ctrlr_name)return -1 ; } +static int +spdk_vhost_dev_find_id_all (const char *ctrlr_name,int *all_id) { +unsigned i, vdev_num =0 ; +size_t dev_dirname_len =strlen (dev_dirname); + +if (strncmp (ctrlr_name, dev_dirname, dev_dirname_len) ==0 ) { + ctrlr_name += dev_dirname_len; + } + +for (i =0 ; i <MAX_VHOST_DEVICES ; i++) { +if (g_spdk_vhost_devices[i] ==NULL ) { +continue ; + } + +if (strcmp (g_spdk_vhost_devices[i]->name, ctrlr_name) ==0 ) { + all_id[vdev_num++] = i; +assert (vdev_num <=MAX_CONNECT_DEVS ); + } + } + +return vdev_num; +} +struct spdk_vhost_dev *spdk_vhost_dev_find (const char *ctrlr_name) {
@@ -469,6 +492,22 @@ spdk_vhost_dev_find(const char *ctrlr_name)return g_spdk_vhost_devices[id]; } +int +spdk_vhost_dev_find_all (const char *ctrlr_name,struct spdk_vhost_dev **vdevs) +{ +int all_id[MAX_CONNECT_DEVS ]; +int vdev_num =0 , i; + + vdev_num =spdk_vhost_dev_find_id_all (ctrlr_name, all_id); +assert (vdev_num <=MAX_CONNECT_DEVS ); + +for (i =0 ; i < vdev_num; i++) { + vdevs[i] = g_spdk_vhost_devices[all_id[i]]; + } + +return vdev_num; +} +static int spdk_vhost_parse_core_mask (const char *mask,uint64_t *cpumask) {
@@ -509,6 +548,7 @@ spdk_vhost_dev_construct(struct spdk_vhost_dev *vdev, const char *name, const chstruct stat file_stat;char buf[64 ];uint64_t cpumask; +bool socket_started = false;assert (vdev);
@@ -523,10 +563,11 @@ spdk_vhost_dev_construct(struct spdk_vhost_dev *vdev, const char *name, const chreturn -EINVAL ; } +if (spdk_vhost_dev_find (name)) { -SPDK_ERRLOG ("vhost controller %s already exists.\n" , name); -return -EEXIST ; - } + socket_started = true; + } +for (ctrlr_num =0 ; ctrlr_num <MAX_VHOST_DEVICES ; ctrlr_num++) {if (g_spdk_vhost_devices[ctrlr_num] ==NULL ) {
@@ -545,6 +586,7 @@ spdk_vhost_dev_construct(struct spdk_vhost_dev *vdev, const char *name, const chreturn -EINVAL ; } +if (!socket_started) {/* Register vhost driver to handle vhost messages. */ if (stat (path, &file_stat) !=-1 ) {if (!S_ISSOCK (file_stat.st_mode)) {
@@ -578,6 +620,7 @@ spdk_vhost_dev_construct(struct spdk_vhost_dev *vdev, const char *name, const chSPDK_ERRLOG ("Couldn't register callbacks for controller %s\n" , name);return -EIO ; } + } vdev->name =strdup (name); vdev->path =strdup (path);
@@ -595,6 +638,7 @@ spdk_vhost_dev_construct(struct spdk_vhost_dev *vdev, const char *name, const ch g_spdk_vhost_devices[ctrlr_num] = vdev; +if (!socket_started) {if (rte_vhost_driver_start (path) !=0 ) {spdk_strerror_r (errno, buf,sizeof (buf)); SPDK_ERRLOG("Failed to start vhost driver for controller %s (%d): %s\n", name, errno,
@@ -604,6 +648,7 @@ spdk_vhost_dev_construct(struct spdk_vhost_dev *vdev, const char *name, const ch }SPDK_NOTICELOG ("Controller %s: new controller added\n" , vdev->name); + }return 0 ; }
@@ -935,6 +980,10 @@ start_device(int vid) } out: +if (rc ==0 ) { +assert (vdev->status &1 ); + vdev->status |=2 ; + }pthread_mutex_unlock (&g_spdk_vhost_mutex);return rc; }
@@ -1058,14 +1107,18 @@ new_connection(int vid)return -1 ; } -/* since pollers are not running it safe not to use spdk_event here */ if (vdev->vid !=-1 ) { -SPDK_ERRLOG ("Device with vid %d is already connected.\n" , vid); -pthread_mutex_unlock (&g_spdk_vhost_mutex); -return -1 ; - } + vdev =spdk_vhost_dev_find_next (vdev); +if (!vdev) { +SPDK_ERRLOG ("Couldn't find unused vdev for vid %d to create connection for.\n" , vid); +pthread_mutex_unlock (&g_spdk_vhost_mutex); +return -1 ; + } + } vdev->vid = vid; +assert (vdev->status ==0 ); + vdev->status |=1 ;pthread_mutex_unlock (&g_spdk_vhost_mutex);return 0 ; }
lib/vhost/vhost_internal.h +7 -0
@@ -67,6 +67,8 @@#define SPDK_VHOST_IOVS_MAX 128 +#define MAX_CONNECT_DEVS 64 +/* * Rate at which stats are checked for interrupt coalescing. */
@@ -134,6 +136,7 @@ struct spdk_vhost_dev_backend {int (*vhost_remove_controller)(struct spdk_vhost_dev *vdev); }; +struct spdk_vhost_scsi_dev ;struct spdk_vhost_dev {struct rte_vhost_memory *mem;char *name;
@@ -146,6 +149,8 @@ struct spdk_vhost_dev {enum spdk_vhost_dev_type type;const struct spdk_vhost_dev_backend *backend; +struct spdk_vhost_scsi_dev *svdev; +uint8_t status;uint32_t coalescing_delay_time_base;
@@ -166,6 +171,8 @@ struct spdk_vhost_dev { };struct spdk_vhost_dev *spdk_vhost_dev_find (const char *ctrlr_name); +struct spdk_vhost_dev *spdk_vhost_dev_find_next (struct spdk_vhost_dev *vdev); +int spdk_vhost_dev_find_all (const char *ctrlr_name,struct spdk_vhost_dev **vdevs);void spdk_vhost_dev_mem_register (struct spdk_vhost_dev *vdev);void spdk_vhost_dev_mem_unregister (struct spdk_vhost_dev *vdev);
lib/vhost/vhost_scsi.c +248 -163
720 lines not on this page · raw message
Signature · 1 line
1.9.1
Ming Lin
RFC PATCH 2/4 support virtio-scsi to reconnect to vhost process when vhost restart
In reply to Ming LinFrom: Sheng Qiu <sheng.qiu(a)alibaba-inc.com>
1. virtio scsi initiator detect io timeout and vhost connection's liveness.
2. reconnect to vhost and resend pending io if current vhost connection is dead
--- include/spdk/io_channel.h | 20 +++- include/spdk_internal/bdev.h | 10 ++ include/spdk_internal/virtio.h | 13 +++ lib/bdev/bdev.c | 2 +- lib/bdev/virtio/bdev_virtio_scsi.c | 201 +++++++++++++++++++++++++++++++++---- lib/util/io_channel.c | 33 +++--- lib/vhost/vhost.c | 1 + lib/virtio/virtio.c | 2 +- lib/virtio/virtio_user.c | 106 +++++++++++++++++++ 9 files changed, 353 insertions(+), 35 deletions(-)
include/spdk/io_channel.h +19 -1
@@ -47,10 +47,10 @@ extern "C" {#endif struct spdk_thread ; -struct spdk_io_channel ;struct spdk_io_channel_iter ;struct spdk_poller ; +typedef void (*spdk_thread_fn )(void *ctx);typedef void (*spdk_thread_pass_msg )(spdk_thread_fn fn,void *ctx,void *thread_ctx);
@@ -70,6 +70,21 @@ typedef void (*spdk_io_device_unregister_cb)(void *io_device);typedef void (*spdk_channel_msg )(struct spdk_io_channel_iter *i);typedef void (*spdk_channel_for_each_cpl )(struct spdk_io_channel_iter *i,int status); +struct spdk_io_channel { +struct spdk_thread *thread; +struct io_device *dev; +uint32_t ref; +TAILQ_ENTRY (spdk_io_channel) tailq; +spdk_io_channel_destroy_cb destroy_cb; + +/* +* Modules will allocate extra memory off the end of this structure +* to store references to hardware-specific references (i.e. NVMe queue +* pairs, or references to child device spdk_io_channels (i.e. +* virtual bdevs). +*/ +}; +/** * \brief Initializes the calling thread for I/O channel allocation. *
@@ -185,6 +200,9 @@ void spdk_io_device_unregister(void *io_device, spdk_io_device_unregister_cb unr*/ struct spdk_io_channel *spdk_get_io_channel (void *io_device); +void spdk_get_all_io_channel (void *io_device,struct spdk_io_channel **ch_array,int size, +int *cnt); +/** * \brief Releases a reference to an I/O channel. This happens asynchronously. *
include/spdk_internal/bdev.h +10 -0
@@ -374,6 +374,15 @@ struct spdk_bdev_io {/** It may be used by modules to put the bdev_io into its own list. */ TAILQ_ENTRY (spdk_bdev_io) module_link; +/** outstanding request queue link */ +TAILQ_ENTRY (spdk_bdev_io) outstanding_req_link; + +/** submit tick */ +uint64_t submit_tick; + +/** The I/O channel that this was submitted on. */ +struct spdk_io_channel *io_ch; +/** * Per I/O context for use by the bdev module. */
@@ -415,6 +424,7 @@ void spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cbvoid spdk_bdev_io_complete (struct spdk_bdev_io *bdev_io,enum spdk_bdev_io_status status); +void spdk_bdev_io_submit (struct spdk_bdev_io *bdev_io);/** * Complete a bdev_io with an NVMe status code. *
include/spdk_internal/virtio.h +13 -0
@@ -46,6 +46,7 @@#include "spdk/json.h" #include "spdk/io_channel.h" #include "spdk/pci_ids.h" +#include "spdk_internal/bdev.h" /** * The maximum virtqueue size is 2^15. Use that value as the end of
@@ -295,6 +296,10 @@ int virtio_dev_start(struct virtio_dev *vdev, uint16_t max_queues,*/ void virtio_dev_stop (struct virtio_dev *vdev); +/* free the allocated queue */ +void +virtio_free_queues (struct virtio_dev *dev); +/** * Destruct a virtio device. Note that it must be in the stopped state. * The virtio_dev should be manually freed afterwards.
@@ -453,6 +458,14 @@ int virtio_pci_dev_enumerate(virtio_pci_create_cb enum_cb, uint16_t pci_device_iint virtio_user_dev_init (struct virtio_dev *vdev,const char *name,const char *path,uint32_t queue_size); +/* check vhost aliveness */ +int +virtio_user_check_vhost_alive (struct virtio_dev *vdev); + +/* reconnect vhost */ +void +virtio_user_dev_reconnect (struct virtio_dev *vdev); +/** * Initialize virtio_dev for a given PCI device. * The virtio_dev has to be freed with \c virtio_dev_destruct.
lib/bdev/bdev.c +1 -1
@@ -767,7 +767,7 @@ spdk_bdev_put_io(struct spdk_bdev_io *bdev_io) } } -static void +void spdk_bdev_io_submit (struct spdk_bdev_io *bdev_io) {struct spdk_bdev *bdev = bdev_io->bdev;
lib/bdev/virtio/bdev_virtio_scsi.c +183 -18
266 lines not on this page · raw message
lib/util/io_channel.c +19 -14
@@ -60,20 +60,6 @@ struct io_device { static TAILQ_HEAD(, io_device) g_io_devices = TAILQ_HEAD_INITIALIZER(g_io_devices); -struct spdk_io_channel { -struct spdk_thread *thread; -struct io_device *dev; -uint32_t ref; -TAILQ_ENTRY (spdk_io_channel) tailq; -spdk_io_channel_destroy_cb destroy_cb; - -/* -* Modules will allocate extra memory off the end of this structure -* to store references to hardware-specific references (i.e. NVMe queue -* pairs, or references to child device spdk_io_channels (i.e. -* virtual bdevs). -*/ -};struct spdk_thread {pthread_t thread_id;
@@ -396,6 +382,25 @@ spdk_io_device_unregister(void *io_device, spdk_io_device_unregister_cb unregist_spdk_io_device_attempt_free (dev); } +void +spdk_get_all_io_channel (void *io_device,struct spdk_io_channel **ch_array,int size,int *cnt) +{ +struct spdk_thread *thread; +struct spdk_io_channel *ch; +int i =0 ; + + TAILQ_FOREACH(thread, &g_threads, tailq) { + TAILQ_FOREACH(ch, &thread->io_channels, tailq) { +if (ch->dev->io_device == io_device) { + ch_array[i++] = ch; +assert (i < size); + } + } + } + + *cnt = i; +} +struct spdk_io_channel *spdk_get_io_channel (void *io_device) {
lib/vhost/vhost.c +1 -0
@@ -1138,6 +1138,7 @@ destroy_connection(int vid)/* since pollers are not running it safe not to use spdk_event here */ vdev->vid =-1 ; + vdev->status =0 ;pthread_mutex_unlock (&g_spdk_vhost_mutex); }
lib/virtio/virtio.c +1 -1
@@ -233,7 +233,7 @@ fail_q_alloc:return ret; } -static void +void virtio_free_queues (struct virtio_dev *dev) {uint16_t nr_vq = dev->max_queues;
lib/virtio/virtio_user.c +106 -0
118 lines not on this page · raw message
Signature · 1 line
1.9.1
Ming Lin
RFC PATCH 3/4 Add ScanTarget to optimize spdk app start time
In reply to Ming LinFrom: Ming Lin <ming.lin(a)alibaba-inc.com>
For example,
[VirtioUser0]
Path /var/run/vhost.nvme0
Queues 3
Name nvme0
ScanTarget 0
"ScanTarget 0" tells virtio scsi only scans vhost target 0. If not specified, will do a full scan.
--- lib/bdev/virtio/bdev_virtio_scsi.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-)
lib/bdev/virtio/bdev_virtio_scsi.c +23 -6
@@ -97,6 +97,8 @@ struct virtio_scsi_dev {/** protect reconnect process */ pthread_mutex_t reconn_mutex; + +int scan_target; };struct virtio_scsi_io_ctx {
@@ -351,6 +353,8 @@ virtio_user_scsi_dev_create(const char *name, const char *path,return NULL ; } + svdev->scan_target =-1 ; + vdev = &svdev->vdev; rc =virtio_user_dev_init (vdev, name, path, queue_size);if (rc !=0 ) {
@@ -869,8 +873,13 @@ bdev_virtio_poll(void *arg)if (scan_ctx->restart) { scan_ctx->restart = false; - scan_ctx->full_scan = true; -_virtio_scsi_dev_scan_tgt (scan_ctx,0 ); +if (svdev->scan_target ==-1 ) { + scan_ctx->full_scan = true; +_virtio_scsi_dev_scan_tgt (scan_ctx,0 ); + }else { + scan_ctx->full_scan = false; +_virtio_scsi_dev_scan_tgt (scan_ctx, svdev->scan_target); + }continue ; }
@@ -1588,6 +1597,7 @@ bdev_virtio_process_config(void)char *path, *name;unsigned vdev_num;int num_queues; +int scan_target;bool enable_pci;int rc =0 ;
@@ -1629,6 +1639,9 @@ bdev_virtio_process_config(void) rc =-1 ; goto out; } + + scan_target =spdk_conf_section_get_intval (sp,"ScanTarget" ); + svdev->scan_target = scan_target; } sp =spdk_conf_find_section (NULL ,"VirtioPci" );
@@ -1734,9 +1747,13 @@ virtio_scsi_dev_scan(struct virtio_scsi_dev *svdev, bdev_virtio_create_cb cb_fn, base = svdev->scan_ctx; base->cb_fn = cb_fn; base->cb_arg = cb_arg; - base->full_scan = true; - -_virtio_scsi_dev_scan_tgt (base,0 ); +if (svdev->scan_target ==-1 ) { + base->full_scan = true; +_virtio_scsi_dev_scan_tgt (base,0 ); + }else { + base->full_scan = false; +_virtio_scsi_dev_scan_tgt (base, svdev->scan_target); + }return 0 ; }
@@ -1766,7 +1783,7 @@ virtio_scsi_dev_scan_tgt(struct virtio_scsi_dev *svdev, uint8_t target) } base = svdev->scan_ctx; - base->full_scan = true; + base->full_scan = (svdev->scan_target ==-1 ) ? true : false;_virtio_scsi_dev_scan_tgt (base, target);return 0 ; }
Signature · 1 line
1.9.1
Ming Lin
RFC PATCH 4/4 rpc: add blocked version of rpc server with epoll
In reply to Ming LinFrom: Ming Lin <ming.lin(a)alibaba-inc.com>
Instead of busy polling, rpc server sleeps if nothing to handle.
--- include/spdk/jsonrpc.h | 4 ++++ include/spdk/rpc.h | 1 + lib/jsonrpc/jsonrpc_internal.h | 1 + lib/jsonrpc/jsonrpc_server_tcp.c | 36 ++++++++++++++++++++++++++++-- lib/rpc/rpc.c | 47 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 2 deletions(-)
include/spdk/jsonrpc.h +4 -0
@@ -74,6 +74,10 @@ int spdk_jsonrpc_server_poll(struct spdk_jsonrpc_server *server);void spdk_jsonrpc_server_shutdown (struct spdk_jsonrpc_server *server); +int spdk_jsonrpc_server_sockfd (struct spdk_jsonrpc_server *server); + +void spdk_jsonrpc_server_set_efd (struct spdk_jsonrpc_server *server,int efd); +/** * Begin building a response to a JSON-RPC request. *
include/spdk/rpc.h +1 -0
@@ -44,6 +44,7 @@ extern "C" {int spdk_rpc_listen (const char *listen_addr);void spdk_rpc_accept (void ); +void spdk_rpc_accept_epoll (void );void spdk_rpc_close (void ); typedef void (*spdk_rpc_method_handler)(struct spdk_jsonrpc_request *request,
lib/jsonrpc/jsonrpc_internal.h +1 -0
@@ -73,6 +73,7 @@ struct spdk_jsonrpc_server_conn {struct spdk_jsonrpc_server {int sockfd; +int efd;spdk_jsonrpc_handle_request_fn handle_request;struct spdk_jsonrpc_server_conn conns[SPDK_JSONRPC_MAX_CONNS ];int num_conns;
lib/jsonrpc/jsonrpc_server_tcp.c +34 -2
@@ -33,6 +33,7 @@#include "jsonrpc_internal.h" #include "spdk/string.h" +#include <sys/epoll.h> struct spdk_jsonrpc_server * spdk_jsonrpc_server_listen(int domain, int protocol,
@@ -103,6 +104,9 @@ spdk_jsonrpc_server_shutdown(struct spdk_jsonrpc_server *server)close (server->conns[i].sockfd); } +if (server->efd >0 ) +close (server->efd); +free (server); }
@@ -112,6 +116,10 @@ spdk_jsonrpc_server_conn_close(struct spdk_jsonrpc_server_conn *conn) conn->closed = true;if (conn->sockfd >=0 ) { +if (conn->server->efd >0 ) { +epoll_ctl (conn->server->efd,EPOLL_CTL_DEL , + conn->sockfd,NULL ); + }close (conn->sockfd); conn->sockfd =-1 ; }
@@ -165,6 +173,20 @@ spdk_jsonrpc_server_accept(struct spdk_jsonrpc_server *server)return -1 ; } +if (server->efd >0 ) { +struct epoll_event event; +int r; + + event.data.fd = conn->sockfd; + event.events =EPOLLIN |EPOLLET ; + r =epoll_ctl (server->efd,EPOLL_CTL_ADD , conn->sockfd, &event); +if (r <0 ) { +spdk_strerror_r (errno, buf,sizeof (buf)); +SPDK_ERRLOG ("epoll_ctl error for socket, fd: %d (%s)\n" , conn->sockfd, buf); +return -1 ; + } + } + server->num_conns++;return 0 ;
@@ -368,13 +390,13 @@ spdk_jsonrpc_server_poll(struct spdk_jsonrpc_server *server)continue ; } - rc =spdk_jsonrpc_server_conn_send (conn); + rc =spdk_jsonrpc_server_conn_recv (conn);if (rc !=0 ) {spdk_jsonrpc_server_conn_close (conn);continue ; } - rc =spdk_jsonrpc_server_conn_recv (conn); + rc =spdk_jsonrpc_server_conn_send (conn);if (rc !=0 ) {spdk_jsonrpc_server_conn_close (conn);continue ;
@@ -383,3 +405,13 @@ spdk_jsonrpc_server_poll(struct spdk_jsonrpc_server *server)return 0 ; } + +int spdk_jsonrpc_server_sockfd (struct spdk_jsonrpc_server *server) +{ +return server->sockfd; +} + +void spdk_jsonrpc_server_set_efd (struct spdk_jsonrpc_server *server,int efd) +{ + server->efd = efd; +}
lib/rpc/rpc.c +47 -0
59 lines not on this page · raw message
Signature · 1 line
1.9.1
Wodkowski
Those patches look promising. We don't review patches on mailing list, can you make a review on gerrithub?
Pawel
Quoted 30 lines
-----Original Message-----
From: SPDK [mailto:spdk-bounces(a)lists.01.org] On Behalf Of Ming Lin
Sent: Friday, May 11, 2018 5:26 AM
To: spdk(a)lists.01.org
Cc: Sheng Qiu <sheng.qiu(a)alibaba-inc.com>; caijin.caij(a)alibaba-inc.com
Subject: [SPDK] [RFC PATCH 0/4]: Alibaba patches for SPDK summit discussionFrom: Ming Lin <ming.lin(a)alibaba-inc.com>
Hi,
Here are some of the patches we'd like to discuss at the comming SPDK summit.
Patches were based on SPDK v17.10 and can't be applied cleanly on upstream SPDK.
But it should be OK for discussion.[RFC PATCH 1/4] changed vhost to support multi-process access same target [RFC PATCH 2/4] support virtio-scsi to reconnect to vhost process when vhost restart
[RFC PATCH 3/4] add ScanTarget to optimize spdk app start time [RFC PATCH 4/4] rpc: add blocked version of rpc server with epollThanks,
Ming
_______________________________________________
SPDK mailing list
SPDK(a)lists.01.org
https://lists.01.org/mailman/listinfo/spdk
Ming Lin
Hi Pawel,
We'll port these patches to latest spdk and then make a review on gerrithub.
Thanks.
Quoted 38 lines · PawelX
Those patches look promising. We don't review patches on mailing list, can you make a review on gerrithub?
Pawel
Quoted 24 lines
-----Original Message-----
From: SPDK [mailto:spdk-bounces(a)lists.01.org] On Behalf Of Ming Lin
Sent: Friday, May 11, 2018 5:26 AM
To: spdk(a)lists.01.org
Cc: Sheng Qiu <sheng.qiu(a)alibaba-inc.com>; caijin.caij(a)alibaba-inc.com
Subject: [SPDK] [RFC PATCH 0/4]: Alibaba patches for SPDK summit discussionFrom: Ming Lin <ming.lin(a)alibaba-inc.com>
Hi,
Here are some of the patches we'd like to discuss at the comming SPDK summit.
Patches were based on SPDK v17.10 and can't be applied cleanly on upstream SPDK.
But it should be OK for discussion.[RFC PATCH 1/4] changed vhost to support multi-process access same target [RFC PATCH 2/4] support virtio-scsi to reconnect to vhost process when vhost restart
[RFC PATCH 3/4] add ScanTarget to optimize spdk app start time [RFC PATCH 4/4] rpc: add blocked version of rpc server with epollQuoted 6 lines
Thanks,
Ming
_______________________________________________
SPDK mailing list
SPDK(a)lists.01.org
https://lists.01.org/mailman/listinfo/spdk_______________________________________________
SPDK mailing list
SPDK(a)lists.01.org
https://lists.01.org/mailman/listinfo/spdk