lib/vhost: start device asynchronously

Now we will start the device(virtio-blk and virtio-scsi) when
there is a valid I/O queue(VRING_KICK message), the backend
device `start_session` callback will ensure this check, so
when processing VRING_KICK messages for each vring, we can
just call `new_device` if `started` is false, and if `started`
is true, it means the device is already started, it's safe
for us to add one more vring even the device is started.

With this change, we don't need to wait for the return value
of `start_session` in synchronous mode, just return is OK.

Fix #2518.

Change-Id: I92ba3d4e5c38422d7697c1d13180a4a48f0dd4cd
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14981
Community-CI: Mellanox Build Bot
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Changpeng Liu 2022-10-14 10:26:45 +08:00 committed by Tomasz Zawadzki
parent 23baa6761d
commit 9da4e15c5c

View File

@ -975,23 +975,23 @@ new_connection(int vid)
return 0; return 0;
} }
static int static void
vhost_user_session_start_cb(struct spdk_vhost_dev *vdev, vhost_user_session_start(void *arg1)
struct spdk_vhost_session *vsession, void *unused)
{ {
struct spdk_vhost_session *vsession = arg1;
struct spdk_vhost_dev *vdev = vsession->vdev;
struct spdk_vhost_user_dev *user_dev = to_user_dev(vsession->vdev);
const struct spdk_vhost_user_dev_backend *backend; const struct spdk_vhost_user_dev_backend *backend;
int rc; int rc;
backend = to_user_dev(vdev)->user_backend; backend = user_dev->user_backend;
rc = backend->start_session(vdev, vsession, NULL); rc = backend->start_session(vdev, vsession, NULL);
vhost_user_session_start_done(vsession, rc); if (rc == 0) {
return rc; vsession->started = true;
}
static int assert(user_dev->active_session_num < UINT32_MAX);
vhost_user_session_start(struct spdk_vhost_dev *vdev, struct spdk_vhost_session *vsession) user_dev->active_session_num++;
{ }
return vhost_user_session_send_event(vsession, vhost_user_session_start_cb, 3, "start session");
} }
static int static int
@ -1120,34 +1120,32 @@ start_device(int vid)
{ {
struct spdk_vhost_dev *vdev; struct spdk_vhost_dev *vdev;
struct spdk_vhost_session *vsession; struct spdk_vhost_session *vsession;
int rc = -1; int rc = 0;
spdk_vhost_lock(); spdk_vhost_lock();
vsession = vhost_session_find_by_vid(vid); vsession = vhost_session_find_by_vid(vid);
if (vsession == NULL) { if (vsession == NULL) {
rc = -1;
SPDK_ERRLOG("Couldn't find session with vid %d.\n", vid); SPDK_ERRLOG("Couldn't find session with vid %d.\n", vid);
goto out; goto out;
} }
vdev = vsession->vdev;
if (vsession->started) { if (vsession->started) {
/* already started, nothing to do */ /* already started, nothing to do */
rc = 0;
goto out; goto out;
} }
if (!vsession->mem) { if (!vsession->mem) {
rc = -1;
SPDK_ERRLOG("Session %s doesn't set memory table yet\n", vsession->name); SPDK_ERRLOG("Session %s doesn't set memory table yet\n", vsession->name);
goto out; goto out;
} }
vdev = vsession->vdev;
vhost_user_session_set_coalescing(vdev, vsession, NULL); vhost_user_session_set_coalescing(vdev, vsession, NULL);
vsession->initialized = true; vsession->initialized = true;
rc = vhost_user_session_start(vdev, vsession); spdk_thread_send_msg(vdev->thread, vhost_user_session_start, vsession);
if (rc != 0) {
goto out;
}
out: out:
spdk_vhost_unlock(); spdk_vhost_unlock();
@ -1275,20 +1273,6 @@ vhost_session_cb_done(int rc)
sem_post(&g_dpdk_sem); sem_post(&g_dpdk_sem);
} }
void
vhost_user_session_start_done(struct spdk_vhost_session *vsession, int response)
{
struct spdk_vhost_user_dev *user_dev = to_user_dev(vsession->vdev);
if (response == 0) {
vsession->started = true;
assert(user_dev->active_session_num < UINT32_MAX);
user_dev->active_session_num++;
}
vhost_session_cb_done(response);
}
void void
vhost_user_session_stop_done(struct spdk_vhost_session *vsession, int response) vhost_user_session_stop_done(struct spdk_vhost_session *vsession, int response)
{ {