Commit d7cd645c authored by Tomasz Zawadzki's avatar Tomasz Zawadzki
Browse files

lib/vhost: move rest of vsession managment to rte_vhost_user



Remaining functions that manage or interact with vsessions
are now placed in rte_vhost_user.
Renamed the functions appropriately with vhost_user_* prefix.

While here g_dpdk_sem was made static, since rest of references
from vhost.c was removed.

Signed-off-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: Ie9fbf5f08910c136711fb1dfab1b35a5488f0c25

Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11025


Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 8ca52b6d
Loading
Loading
Loading
Loading
+225 −3
Original line number Diff line number Diff line
@@ -48,7 +48,36 @@

/* Path to folder where character device will be created. Can be set by user. */
static char g_vhost_user_dev_dirname[PATH_MAX] = "";
sem_t g_dpdk_sem;

/**
 * DPDK calls our callbacks synchronously but the work those callbacks
 * perform needs to be async. Luckily, all DPDK callbacks are called on
 * a DPDK-internal pthread, so we'll just wait on a semaphore in there.
 */
static sem_t g_dpdk_sem;

/** Return code for the current DPDK callback */
static int g_dpdk_response;

struct vhost_session_fn_ctx {
	/** Device pointer obtained before enqueueing the event */
	struct spdk_vhost_dev *vdev;

	/** ID of the session to send event to. */
	uint32_t vsession_id;

	/** User provided function to be executed on session's thread. */
	spdk_vhost_session_fn cb_fn;

	/**
	 * User provided function to be called on the init thread
	 * after iterating through all sessions.
	 */
	spdk_vhost_dev_fn cpl_fn;

	/** Custom user context */
	void *user_ctx;
};

static void __attribute__((constructor))
_vhost_user_sem_init(void)
@@ -193,7 +222,7 @@ new_connection(int vid)
	/* We expect sessions inside vdev->vsessions to be sorted in ascending
	 * order in regard of vsession->id. For now we always set id = vsessions_cnt++
	 * and append each session to the very end of the vsessions list.
	 * This is required for spdk_vhost_dev_foreach_session() to work.
	 * This is required for vhost_user_dev_foreach_session() to work.
	 */
	if (vdev->vsessions_num == UINT_MAX) {
		assert(false);
@@ -425,6 +454,199 @@ static const struct vhost_device_ops g_spdk_vhost_ops = {
	.destroy_connection = destroy_connection,
};

static struct spdk_vhost_session *
vhost_session_find_by_id(struct spdk_vhost_dev *vdev, unsigned id)
{
	struct spdk_vhost_session *vsession;

	TAILQ_FOREACH(vsession, &vdev->vsessions, tailq) {
		if (vsession->id == id) {
			return vsession;
		}
	}

	return NULL;
}

struct spdk_vhost_session *
vhost_session_find_by_vid(int vid)
{
	struct spdk_vhost_dev *vdev;
	struct spdk_vhost_session *vsession;

	for (vdev = spdk_vhost_dev_next(NULL); vdev != NULL;
	     vdev = spdk_vhost_dev_next(vdev)) {
		TAILQ_FOREACH(vsession, &vdev->vsessions, tailq) {
			if (vsession->vid == vid) {
				return vsession;
			}
		}
	}

	return NULL;
}

static void
wait_for_semaphore(int timeout_sec, const char *errmsg)
{
	struct timespec timeout;
	int rc;

	clock_gettime(CLOCK_REALTIME, &timeout);
	timeout.tv_sec += timeout_sec;
	rc = sem_timedwait(&g_dpdk_sem, &timeout);
	if (rc != 0) {
		SPDK_ERRLOG("Timeout waiting for event: %s.\n", errmsg);
		sem_wait(&g_dpdk_sem);
	}
}

static void
vhost_session_cb_done(int rc)
{
	g_dpdk_response = rc;
	sem_post(&g_dpdk_sem);
}

void
vhost_user_session_start_done(struct spdk_vhost_session *vsession, int response)
{
	if (response == 0) {
		vsession->started = true;

		assert(vsession->vdev->active_session_num < UINT32_MAX);
		vsession->vdev->active_session_num++;
	}

	vhost_session_cb_done(response);
}

void
vhost_user_session_stop_done(struct spdk_vhost_session *vsession, int response)
{
	if (response == 0) {
		vsession->started = false;

		assert(vsession->vdev->active_session_num > 0);
		vsession->vdev->active_session_num--;
	}

	vhost_session_cb_done(response);
}

static void
vhost_event_cb(void *arg1)
{
	struct vhost_session_fn_ctx *ctx = arg1;
	struct spdk_vhost_session *vsession;

	if (spdk_vhost_trylock() != 0) {
		spdk_thread_send_msg(spdk_get_thread(), vhost_event_cb, arg1);
		return;
	}

	vsession = vhost_session_find_by_id(ctx->vdev, ctx->vsession_id);
	ctx->cb_fn(ctx->vdev, vsession, NULL);
	spdk_vhost_unlock();
}

int
vhost_user_session_send_event(struct spdk_vhost_session *vsession,
			 spdk_vhost_session_fn cb_fn, unsigned timeout_sec,
			 const char *errmsg)
{
	struct vhost_session_fn_ctx ev_ctx = {0};
	struct spdk_vhost_dev *vdev = vsession->vdev;

	ev_ctx.vdev = vdev;
	ev_ctx.vsession_id = vsession->id;
	ev_ctx.cb_fn = cb_fn;

	spdk_thread_send_msg(vdev->thread, vhost_event_cb, &ev_ctx);

	spdk_vhost_unlock();
	wait_for_semaphore(timeout_sec, errmsg);
	spdk_vhost_lock();

	return g_dpdk_response;
}

static void
foreach_session_finish_cb(void *arg1)
{
	struct vhost_session_fn_ctx *ev_ctx = arg1;
	struct spdk_vhost_dev *vdev = ev_ctx->vdev;

	if (spdk_vhost_trylock() != 0) {
		spdk_thread_send_msg(spdk_get_thread(),
				     foreach_session_finish_cb, arg1);
		return;
	}

	assert(vdev->pending_async_op_num > 0);
	vdev->pending_async_op_num--;
	if (ev_ctx->cpl_fn != NULL) {
		ev_ctx->cpl_fn(vdev, ev_ctx->user_ctx);
	}

	spdk_vhost_unlock();
	free(ev_ctx);
}

static void
foreach_session(void *arg1)
{
	struct vhost_session_fn_ctx *ev_ctx = arg1;
	struct spdk_vhost_session *vsession;
	struct spdk_vhost_dev *vdev = ev_ctx->vdev;
	int rc;

	if (spdk_vhost_trylock() != 0) {
		spdk_thread_send_msg(spdk_get_thread(), foreach_session, arg1);
		return;
	}

	TAILQ_FOREACH(vsession, &vdev->vsessions, tailq) {
		if (vsession->initialized) {
			rc = ev_ctx->cb_fn(vdev, vsession, ev_ctx->user_ctx);
			if (rc < 0) {
				goto out;
			}
		}
	}

out:
	spdk_vhost_unlock();

	spdk_thread_send_msg(g_vhost_init_thread, foreach_session_finish_cb, arg1);
}

void
vhost_user_dev_foreach_session(struct spdk_vhost_dev *vdev,
			  spdk_vhost_session_fn fn,
			  spdk_vhost_dev_fn cpl_fn,
			  void *arg)
{
	struct vhost_session_fn_ctx *ev_ctx;

	ev_ctx = calloc(1, sizeof(*ev_ctx));
	if (ev_ctx == NULL) {
		SPDK_ERRLOG("Failed to alloc vhost event.\n");
		assert(false);
		return;
	}

	ev_ctx->vdev = vdev;
	ev_ctx->cb_fn = fn;
	ev_ctx->cpl_fn = cpl_fn;
	ev_ctx->user_ctx = arg;

	assert(vdev->pending_async_op_num < UINT32_MAX);
	vdev->pending_async_op_num++;

	spdk_thread_send_msg(vdev->thread, foreach_session, ev_ctx);
}

void
vhost_user_session_set_interrupt_mode(struct spdk_vhost_session *vsession, bool interrupt_mode)
{
@@ -763,7 +985,7 @@ spdk_vhost_set_coalescing(struct spdk_vhost_dev *vdev, uint32_t delay_base_us,
		return rc;
	}

	vhost_dev_foreach_session(vdev, vhost_user_session_set_coalescing, NULL, NULL);
	vhost_user_dev_foreach_session(vdev, vhost_user_session_set_coalescing, NULL, NULL);
	return 0;
}

+0 −216
Original line number Diff line number Diff line
@@ -49,29 +49,6 @@ static struct spdk_cpuset g_vhost_core_mask;
/* Thread performing all vhost management operations */
struct spdk_thread *g_vhost_init_thread = NULL;

/** Return code for the current DPDK callback */
static int g_dpdk_response;

struct vhost_session_fn_ctx {
	/** Device pointer obtained before enqueueing the event */
	struct spdk_vhost_dev *vdev;

	/** ID of the session to send event to. */
	uint32_t vsession_id;

	/** User provided function to be executed on session's thread. */
	spdk_vhost_session_fn cb_fn;

	/**
	 * User provided function to be called on the init thread
	 * after iterating through all sessions.
	 */
	spdk_vhost_dev_fn cpl_fn;

	/** Custom user context */
	void *user_ctx;
};

static TAILQ_HEAD(, spdk_vhost_dev) g_vhost_devices = TAILQ_HEAD_INITIALIZER(
			g_vhost_devices);
static pthread_mutex_t g_vhost_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -752,38 +729,6 @@ vhost_vring_desc_to_iov(struct spdk_vhost_session *vsession, struct iovec *iov,
					       desc->addr, desc->len);
}

static struct spdk_vhost_session *
vhost_session_find_by_id(struct spdk_vhost_dev *vdev, unsigned id)
{
	struct spdk_vhost_session *vsession;

	TAILQ_FOREACH(vsession, &vdev->vsessions, tailq) {
		if (vsession->id == id) {
			return vsession;
		}
	}

	return NULL;
}

struct spdk_vhost_session *
vhost_session_find_by_vid(int vid)
{
	struct spdk_vhost_dev *vdev;
	struct spdk_vhost_session *vsession;

	for (vdev = spdk_vhost_dev_next(NULL); vdev != NULL;
	     vdev = spdk_vhost_dev_next(vdev)) {
		TAILQ_FOREACH(vsession, &vdev->vsessions, tailq) {
			if (vsession->vid == vid) {
				return vsession;
			}
		}
	}

	return NULL;
}

struct spdk_vhost_dev *
spdk_vhost_dev_next(struct spdk_vhost_dev *vdev)
{
@@ -922,167 +867,6 @@ spdk_vhost_dev_get_cpumask(struct spdk_vhost_dev *vdev)
	return spdk_thread_get_cpumask(vdev->thread);
}

static void
wait_for_semaphore(int timeout_sec, const char *errmsg)
{
	struct timespec timeout;
	int rc;

	clock_gettime(CLOCK_REALTIME, &timeout);
	timeout.tv_sec += timeout_sec;
	rc = sem_timedwait(&g_dpdk_sem, &timeout);
	if (rc != 0) {
		SPDK_ERRLOG("Timeout waiting for event: %s.\n", errmsg);
		sem_wait(&g_dpdk_sem);
	}
}

static void
vhost_session_cb_done(int rc)
{
	g_dpdk_response = rc;
	sem_post(&g_dpdk_sem);
}

void
vhost_session_start_done(struct spdk_vhost_session *vsession, int response)
{
	if (response == 0) {
		vsession->started = true;

		assert(vsession->vdev->active_session_num < UINT32_MAX);
		vsession->vdev->active_session_num++;
	}

	vhost_session_cb_done(response);
}

void
vhost_session_stop_done(struct spdk_vhost_session *vsession, int response)
{
	if (response == 0) {
		vsession->started = false;

		assert(vsession->vdev->active_session_num > 0);
		vsession->vdev->active_session_num--;
	}

	vhost_session_cb_done(response);
}

static void
vhost_event_cb(void *arg1)
{
	struct vhost_session_fn_ctx *ctx = arg1;
	struct spdk_vhost_session *vsession;

	if (spdk_vhost_trylock() != 0) {
		spdk_thread_send_msg(spdk_get_thread(), vhost_event_cb, arg1);
		return;
	}

	vsession = vhost_session_find_by_id(ctx->vdev, ctx->vsession_id);
	ctx->cb_fn(ctx->vdev, vsession, NULL);
	spdk_vhost_unlock();
}

int
vhost_session_send_event(struct spdk_vhost_session *vsession,
			 spdk_vhost_session_fn cb_fn, unsigned timeout_sec,
			 const char *errmsg)
{
	struct vhost_session_fn_ctx ev_ctx = {0};
	struct spdk_vhost_dev *vdev = vsession->vdev;

	ev_ctx.vdev = vdev;
	ev_ctx.vsession_id = vsession->id;
	ev_ctx.cb_fn = cb_fn;

	spdk_thread_send_msg(vdev->thread, vhost_event_cb, &ev_ctx);

	spdk_vhost_unlock();
	wait_for_semaphore(timeout_sec, errmsg);
	spdk_vhost_lock();

	return g_dpdk_response;
}

static void
foreach_session_finish_cb(void *arg1)
{
	struct vhost_session_fn_ctx *ev_ctx = arg1;
	struct spdk_vhost_dev *vdev = ev_ctx->vdev;

	if (spdk_vhost_trylock() != 0) {
		spdk_thread_send_msg(spdk_get_thread(),
				     foreach_session_finish_cb, arg1);
		return;
	}

	assert(vdev->pending_async_op_num > 0);
	vdev->pending_async_op_num--;
	if (ev_ctx->cpl_fn != NULL) {
		ev_ctx->cpl_fn(vdev, ev_ctx->user_ctx);
	}

	spdk_vhost_unlock();
	free(ev_ctx);
}

static void
foreach_session(void *arg1)
{
	struct vhost_session_fn_ctx *ev_ctx = arg1;
	struct spdk_vhost_session *vsession;
	struct spdk_vhost_dev *vdev = ev_ctx->vdev;
	int rc;

	if (spdk_vhost_trylock() != 0) {
		spdk_thread_send_msg(spdk_get_thread(), foreach_session, arg1);
		return;
	}

	TAILQ_FOREACH(vsession, &vdev->vsessions, tailq) {
		if (vsession->initialized) {
			rc = ev_ctx->cb_fn(vdev, vsession, ev_ctx->user_ctx);
			if (rc < 0) {
				goto out;
			}
		}
	}

out:
	spdk_vhost_unlock();

	spdk_thread_send_msg(g_vhost_init_thread, foreach_session_finish_cb, arg1);
}

void
vhost_dev_foreach_session(struct spdk_vhost_dev *vdev,
			  spdk_vhost_session_fn fn,
			  spdk_vhost_dev_fn cpl_fn,
			  void *arg)
{
	struct vhost_session_fn_ctx *ev_ctx;

	ev_ctx = calloc(1, sizeof(*ev_ctx));
	if (ev_ctx == NULL) {
		SPDK_ERRLOG("Failed to alloc vhost event.\n");
		assert(false);
		return;
	}

	ev_ctx->vdev = vdev;
	ev_ctx->cb_fn = fn;
	ev_ctx->cpl_fn = cpl_fn;
	ev_ctx->user_ctx = arg;

	assert(vdev->pending_async_op_num < UINT32_MAX);
	vdev->pending_async_op_num++;

	spdk_thread_send_msg(vdev->thread, foreach_session, ev_ctx);
}

void
vhost_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w)
{
+12 −12
Original line number Diff line number Diff line
@@ -1111,7 +1111,7 @@ blk_resize_cb(void *resize_ctx)
	struct spdk_vhost_blk_dev *bvdev = resize_ctx;

	spdk_vhost_lock();
	vhost_dev_foreach_session(&bvdev->vdev, vhost_session_bdev_resize_cb,
	vhost_user_dev_foreach_session(&bvdev->vdev, vhost_session_bdev_resize_cb,
				       NULL, NULL);
	spdk_vhost_unlock();
}
@@ -1168,7 +1168,7 @@ bdev_remove_cb(void *remove_ctx)
		     bvdev->vdev.name);

	spdk_vhost_lock();
	vhost_dev_foreach_session(&bvdev->vdev, vhost_session_bdev_remove_cb,
	vhost_user_dev_foreach_session(&bvdev->vdev, vhost_session_bdev_remove_cb,
				       vhost_dev_bdev_remove_cpl_cb, NULL);
	spdk_vhost_unlock();
}
@@ -1328,14 +1328,14 @@ vhost_blk_start_cb(struct spdk_vhost_dev *vdev,
				       bvsession);

out:
	vhost_session_start_done(vsession, rc);
	vhost_user_session_start_done(vsession, rc);
	return rc;
}

static int
vhost_blk_start(struct spdk_vhost_session *vsession)
{
	return vhost_session_send_event(vsession, vhost_blk_start_cb,
	return vhost_user_session_send_event(vsession, vhost_blk_start_cb,
					     3, "start session");
}

@@ -1353,7 +1353,7 @@ destroy_session_poller_cb(void *arg)
			SPDK_ERRLOG("%s: Timedout when destroy session (task_cnt %d)\n", vsession->name,
				    vsession->task_cnt);
			spdk_poller_unregister(&bvsession->stop_poller);
			vhost_session_stop_done(vsession, -ETIMEDOUT);
			vhost_user_session_stop_done(vsession, -ETIMEDOUT);
		}

		return SPDK_POLLER_BUSY;
@@ -1374,7 +1374,7 @@ destroy_session_poller_cb(void *arg)

	free_task_pool(bvsession);
	spdk_poller_unregister(&bvsession->stop_poller);
	vhost_session_stop_done(vsession, 0);
	vhost_user_session_stop_done(vsession, 0);

	spdk_vhost_unlock();
	return SPDK_POLLER_BUSY;
@@ -1392,7 +1392,7 @@ vhost_blk_stop_cb(struct spdk_vhost_dev *vdev,
		vhost_blk_session_unregister_interrupts(bvsession);
	}

	/* vhost_session_send_event timeout is 3 seconds, here set retry within 4 seconds */
	/* vhost_user_session_send_event timeout is 3 seconds, here set retry within 4 seconds */
	bvsession->vsession.stop_retry_count = 4000;
	bvsession->stop_poller = SPDK_POLLER_REGISTER(destroy_session_poller_cb,
				 bvsession, 1000);
@@ -1402,7 +1402,7 @@ vhost_blk_stop_cb(struct spdk_vhost_dev *vdev,
static int
vhost_blk_stop(struct spdk_vhost_session *vsession)
{
	return vhost_session_send_event(vsession, vhost_blk_stop_cb,
	return vhost_user_session_send_event(vsession, vhost_blk_stop_cb,
					     3, "stop session");
}

+14 −21
Original line number Diff line number Diff line
@@ -50,13 +50,6 @@ extern bool g_packed_ring_recovery;
/* Thread performing all vhost management operations */
extern struct spdk_thread *g_vhost_init_thread;

/**
 * DPDK calls our callbacks synchronously but the work those callbacks
 * perform needs to be async. Luckily, all DPDK callbacks are called on
 * a DPDK-internal pthread, so we'll just wait on a semaphore in there.
 */
extern sem_t g_dpdk_sem;

#define SPDK_VHOST_MAX_VQUEUES	256
#define SPDK_VHOST_MAX_VQ_SIZE	1024

@@ -443,14 +436,14 @@ void vhost_session_mem_unregister(struct rte_vhost_memory *mem);
 * Optional, can be NULL.
 * \param arg additional argument to the both callbacks
 */
void vhost_dev_foreach_session(struct spdk_vhost_dev *dev,
void vhost_user_dev_foreach_session(struct spdk_vhost_dev *dev,
				    spdk_vhost_session_fn fn,
				    spdk_vhost_dev_fn cpl_fn,
				    void *arg);

/**
 * Call a function on the provided lcore and block until either
 * spdk_vhost_session_start_done() or spdk_vhost_session_stop_done()
 * vhost_user_session_start_done() or vhost_user_session_stop_done()
 * is called.
 *
 * This must be called under the global vhost mutex, which this function
@@ -465,28 +458,28 @@ void vhost_dev_foreach_session(struct spdk_vhost_dev *dev,
 * \param errmsg error message to print once the timeout expires
 * \return return the code passed to spdk_vhost_session_event_done().
 */
int vhost_session_send_event(struct spdk_vhost_session *vsession,
int vhost_user_session_send_event(struct spdk_vhost_session *vsession,
				  spdk_vhost_session_fn cb_fn, unsigned timeout_sec,
				  const char *errmsg);

/**
 * Finish a blocking spdk_vhost_session_send_event() call and finally
 * Finish a blocking spdk_vhost_user_session_send_event() call and finally
 * start the session. This must be called on the target lcore, which
 * will now receive all session-related messages (e.g. from
 * spdk_vhost_dev_foreach_session()).
 * vhost_user_dev_foreach_session()).
 *
 * Must be called under the global vhost lock.
 *
 * \param vsession vhost session
 * \param response return code
 */
void vhost_session_start_done(struct spdk_vhost_session *vsession, int response);
void vhost_user_session_start_done(struct spdk_vhost_session *vsession, int response);

/**
 * Finish a blocking spdk_vhost_session_send_event() call and finally
 * Finish a blocking spdk_vhost_user_session_send_event() call and finally
 * stop the session. This must be called on the session's lcore which
 * used to receive all session-related messages (e.g. from
 * spdk_vhost_dev_foreach_session()). After this call, the session-
 * vhost_user_dev_foreach_session()). After this call, the session-
 * related messages will be once again processed by any arbitrary thread.
 *
 * Must be called under the global vhost lock.
@@ -496,7 +489,7 @@ void vhost_session_start_done(struct spdk_vhost_session *vsession, int response)
 * \param vsession vhost session
 * \param response return code
 */
void vhost_session_stop_done(struct spdk_vhost_session *vsession, int response);
void vhost_user_session_stop_done(struct spdk_vhost_session *vsession, int response);

struct spdk_vhost_session *vhost_session_find_by_vid(int vid);
void vhost_session_install_rte_compat_hooks(struct spdk_vhost_session *vsession);
+23 −23
Original line number Diff line number Diff line
@@ -267,7 +267,7 @@ process_removed_devs(struct spdk_vhost_scsi_session *svsession)
			state->status = VHOST_SCSI_DEV_REMOVED;
			/* try to detach it globally */
			spdk_vhost_lock();
			vhost_dev_foreach_session(&svsession->svdev->vdev,
			vhost_user_dev_foreach_session(&svsession->svdev->vdev,
						       vhost_scsi_session_process_removed,
						       vhost_scsi_dev_process_removed_cpl_cb,
						       (void *)(uintptr_t)i);
@@ -1127,7 +1127,7 @@ spdk_vhost_scsi_dev_add_tgt(struct spdk_vhost_dev *vdev, int scsi_tgt_num,
	SPDK_INFOLOG(vhost, "%s: added SCSI target %u using bdev '%s'\n",
		     vdev->name, scsi_tgt_num, bdev_name);

	vhost_dev_foreach_session(vdev, vhost_scsi_session_add_tgt,
	vhost_user_dev_foreach_session(vdev, vhost_scsi_session_add_tgt,
				       vhost_scsi_dev_add_tgt_cpl_cb,
				       (void *)(uintptr_t)scsi_tgt_num);
	return scsi_tgt_num;
@@ -1228,7 +1228,7 @@ spdk_vhost_scsi_dev_remove_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_nu
	scsi_dev_state->remove_ctx = cb_arg;
	scsi_dev_state->status = VHOST_SCSI_DEV_REMOVING;

	vhost_dev_foreach_session(vdev, vhost_scsi_session_remove_tgt,
	vhost_user_dev_foreach_session(vdev, vhost_scsi_session_remove_tgt,
				       vhost_scsi_dev_remove_tgt_cpl_cb, ctx);
	return 0;
}
@@ -1295,7 +1295,7 @@ vhost_scsi_dev_param_changed(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num)

	assert(scsi_dev_state->status != VHOST_SCSI_DEV_EMPTY);

	vhost_dev_foreach_session(vdev, vhost_scsi_session_param_changed,
	vhost_user_dev_foreach_session(vdev, vhost_scsi_session_param_changed,
				       NULL, (void *)(uintptr_t)scsi_tgt_num);
	return 0;
}
@@ -1417,7 +1417,7 @@ vhost_scsi_start_cb(struct spdk_vhost_dev *vdev,
	svsession->mgmt_poller = SPDK_POLLER_REGISTER(vdev_mgmt_worker, svsession,
				 MGMT_POLL_PERIOD_US);
out:
	vhost_session_start_done(vsession, rc);
	vhost_user_session_start_done(vsession, rc);
	return rc;
}

@@ -1431,7 +1431,7 @@ vhost_scsi_start(struct spdk_vhost_session *vsession)
	assert(svdev != NULL);
	svsession->svdev = svdev;

	return vhost_session_send_event(vsession, vhost_scsi_start_cb,
	return vhost_user_session_send_event(vsession, vhost_scsi_start_cb,
					     3, "start session");
}

@@ -1450,7 +1450,7 @@ destroy_session_poller_cb(void *arg)
			SPDK_ERRLOG("%s: Timedout when destroy session (task_cnt %d)\n", vsession->name,
				    vsession->task_cnt);
			spdk_poller_unregister(&svsession->stop_poller);
			vhost_session_stop_done(vsession, -ETIMEDOUT);
			vhost_user_session_stop_done(vsession, -ETIMEDOUT);
		}

		return SPDK_POLLER_BUSY;
@@ -1477,7 +1477,7 @@ destroy_session_poller_cb(void *arg)

		if (prev_status == VHOST_SCSI_DEV_REMOVING) {
			/* try to detach it globally */
			vhost_dev_foreach_session(vsession->vdev,
			vhost_user_dev_foreach_session(vsession->vdev,
						       vhost_scsi_session_process_removed,
						       vhost_scsi_dev_process_removed_cpl_cb,
						       (void *)(uintptr_t)i);
@@ -1490,7 +1490,7 @@ destroy_session_poller_cb(void *arg)
	free_task_pool(svsession);

	spdk_poller_unregister(&svsession->stop_poller);
	vhost_session_stop_done(vsession, 0);
	vhost_user_session_stop_done(vsession, 0);

	spdk_vhost_unlock();
	return SPDK_POLLER_BUSY;
@@ -1511,7 +1511,7 @@ vhost_scsi_stop_cb(struct spdk_vhost_dev *vdev,
	 */
	spdk_poller_unregister(&svsession->mgmt_poller);

	/* vhost_session_send_event timeout is 3 seconds, here set retry within 4 seconds */
	/* vhost_user_session_send_event timeout is 3 seconds, here set retry within 4 seconds */
	svsession->vsession.stop_retry_count = 4000;

	/* Wait for all pending I/Os to complete, then process all the
@@ -1526,7 +1526,7 @@ vhost_scsi_stop_cb(struct spdk_vhost_dev *vdev,
static int
vhost_scsi_stop(struct spdk_vhost_session *vsession)
{
	return vhost_session_send_event(vsession, vhost_scsi_stop_cb,
	return vhost_user_session_send_event(vsession, vhost_scsi_stop_cb,
					     3, "stop session");
}