Commit 9da4e15c authored by Changpeng Liu's avatar Changpeng Liu Committed by Tomasz Zawadzki
Browse files

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: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14981


Community-CI: Mellanox Build Bot
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 23baa676
Loading
Loading
Loading
Loading
+16 −32
Original line number Diff line number Diff line
@@ -975,23 +975,23 @@ new_connection(int vid)
	return 0;
}

static int
vhost_user_session_start_cb(struct spdk_vhost_dev *vdev,
			    struct spdk_vhost_session *vsession, void *unused)
static void
vhost_user_session_start(void *arg1)
{
	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;
	int rc;

	backend = to_user_dev(vdev)->user_backend;
	backend = user_dev->user_backend;
	rc = backend->start_session(vdev, vsession, NULL);
	vhost_user_session_start_done(vsession, rc);
	return rc;
}
	if (rc == 0) {
		vsession->started = true;

static int
vhost_user_session_start(struct spdk_vhost_dev *vdev, struct spdk_vhost_session *vsession)
{
	return vhost_user_session_send_event(vsession, vhost_user_session_start_cb, 3, "start session");
		assert(user_dev->active_session_num < UINT32_MAX);
		user_dev->active_session_num++;
	}
}

static int
@@ -1120,34 +1120,32 @@ start_device(int vid)
{
	struct spdk_vhost_dev *vdev;
	struct spdk_vhost_session *vsession;
	int rc = -1;
	int rc = 0;

	spdk_vhost_lock();

	vsession = vhost_session_find_by_vid(vid);
	if (vsession == NULL) {
		rc = -1;
		SPDK_ERRLOG("Couldn't find session with vid %d.\n", vid);
		goto out;
	}

	vdev = vsession->vdev;
	if (vsession->started) {
		/* already started, nothing to do */
		rc = 0;
		goto out;
	}

	if (!vsession->mem) {
		rc = -1;
		SPDK_ERRLOG("Session %s doesn't set memory table yet\n", vsession->name);
		goto out;
	}

	vdev = vsession->vdev;
	vhost_user_session_set_coalescing(vdev, vsession, NULL);
	vsession->initialized = true;
	rc = vhost_user_session_start(vdev, vsession);
	if (rc != 0) {
		goto out;
	}
	spdk_thread_send_msg(vdev->thread, vhost_user_session_start, vsession);

out:
	spdk_vhost_unlock();
@@ -1275,20 +1273,6 @@ vhost_session_cb_done(int rc)
	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
vhost_user_session_stop_done(struct spdk_vhost_session *vsession, int response)
{