diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index b6c5d5576..98caa8b2d 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -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