vhost: finish foreach_session chain always on the init thread
foreach_session() is used to e.g. close a bdev, where for each session we close any io_channels and then, on the final "finish" call, close the bdev descriptor. The vhost init thread is the one that called spdk_vhost_init() and also the same one that calls all management APIs. One of those is for hotplugging LUNs to vhost scsi targets, which practically results in opening bdev descriptors. By always scheduling that final foreach_session() callback to the init thread, we end up with calling spdk_bdev_close() always on the same thread which called spdk_bdev_open(), which is actually a bdev layer requirement. Change-Id: I2338e15c63f93ef37dd4412dd677dee40d272ec2 Signed-off-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/459166 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
parent
4b60bd1b59
commit
3fb1a9565e
@ -985,6 +985,27 @@ static void foreach_session_continue(struct spdk_vhost_dev *vdev,
|
||||
struct spdk_vhost_session *vsession,
|
||||
spdk_vhost_session_fn fn, void *arg);
|
||||
|
||||
static void
|
||||
foreach_session_finish_cb(void *arg1)
|
||||
{
|
||||
struct spdk_vhost_session_fn_ctx *ctx = arg1;
|
||||
struct spdk_vhost_dev *vdev = ctx->vdev;
|
||||
|
||||
if (pthread_mutex_trylock(&g_spdk_vhost_mutex) != 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--;
|
||||
/* Call fn one last time with vsession == NULL */
|
||||
ctx->cb_fn(vdev, NULL, ctx->user_ctx);
|
||||
|
||||
pthread_mutex_unlock(&g_spdk_vhost_mutex);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
foreach_session_continue_cb(void *arg1)
|
||||
{
|
||||
@ -1040,11 +1061,7 @@ foreach_session_continue(struct spdk_vhost_dev *vdev,
|
||||
struct spdk_vhost_session_fn_ctx *ev_ctx;
|
||||
int rc;
|
||||
|
||||
if (vsession == NULL) {
|
||||
goto out_finish_foreach;
|
||||
}
|
||||
|
||||
while (!vsession->started) {
|
||||
while (vsession != NULL && !vsession->started) {
|
||||
if (vsession->initialized) {
|
||||
rc = fn(vdev, vsession, arg);
|
||||
if (rc < 0) {
|
||||
@ -1053,9 +1070,6 @@ foreach_session_continue(struct spdk_vhost_dev *vdev,
|
||||
}
|
||||
|
||||
vsession = spdk_vhost_session_next(vdev, vsession->id);
|
||||
if (vsession == NULL) {
|
||||
goto out_finish_foreach;
|
||||
}
|
||||
}
|
||||
|
||||
ev_ctx = calloc(1, sizeof(*ev_ctx));
|
||||
@ -1066,21 +1080,18 @@ foreach_session_continue(struct spdk_vhost_dev *vdev,
|
||||
}
|
||||
|
||||
ev_ctx->vdev = vdev;
|
||||
ev_ctx->vsession_id = vsession->id;
|
||||
ev_ctx->cb_fn = fn;
|
||||
ev_ctx->user_ctx = arg;
|
||||
|
||||
spdk_thread_send_msg(vsession->poll_group->thread,
|
||||
foreach_session_continue_cb, ev_ctx);
|
||||
return;
|
||||
|
||||
out_finish_foreach:
|
||||
/* there are no more sessions to iterate through, so call the
|
||||
* fn one last time with vsession == NULL
|
||||
*/
|
||||
assert(vdev->pending_async_op_num > 0);
|
||||
vdev->pending_async_op_num--;
|
||||
fn(vdev, NULL, arg);
|
||||
if (vsession != NULL) {
|
||||
ev_ctx->vsession_id = vsession->id;
|
||||
spdk_thread_send_msg(vsession->poll_group->thread,
|
||||
foreach_session_continue_cb, ev_ctx);
|
||||
} else {
|
||||
ev_ctx->vsession_id = UINT32_MAX;
|
||||
spdk_thread_send_msg(g_vhost_init_thread,
|
||||
foreach_session_finish_cb, ev_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user