Commit 840a5d2e authored by xupeng-mingtu's avatar xupeng-mingtu Committed by Konrad Sztyber
Browse files

lib/vhost: fix rpc vhost_delete_controller may block the entire reactor



When shutting down a vm, qemu will disconnect the session connection
with vhost_block_controller. The dpdk-vhost-evt thread will handle the
disconnection and unregister the memory, it will lock "user_dev->lock".
If the vhost_delete_controller rpc is called before the memory
unregister is completed, "user_dev->lock" also needs to be locked,
so it will wait for the dpdk-vhost-evt thread to release the lock.
During the waiting process, the reactor where app_thread is located
will be blocked, causing other IO to not be processed.

Fixes issue #3468

Change-Id: I262b79c8b7ffa260941171b8058b443bcf827cf4
Signed-off-by: default avatarxupeng-mingtu <jingmamour@gmail.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/24402


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarGangCao <gang.cao@intel.com>
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
parent 3f0a3930
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -1855,7 +1855,10 @@ vhost_user_dev_unregister(struct spdk_vhost_dev *vdev)
	struct spdk_vhost_user_dev *user_dev = to_user_dev(vdev);
	struct spdk_vhost_session *vsession, *tmp_vsession;

	pthread_mutex_lock(&user_dev->lock);
	if (pthread_mutex_trylock(&user_dev->lock) != 0) {
		return -EBUSY;
	}

	if (user_dev->pending_async_op_num) {
		pthread_mutex_unlock(&user_dev->lock);
		return -EBUSY;
+30 −0
Original line number Diff line number Diff line
@@ -323,6 +323,13 @@ free_rpc_delete_vhost_ctrlr(struct rpc_delete_vhost_ctrlr *req)
	free(req->ctrlr);
}

struct vhost_delete_ctrlr_context {
	struct spdk_jsonrpc_request *request;
	const struct spdk_json_val *params;
};

static void _rpc_vhost_delete_controller(void *arg);

static void
rpc_vhost_delete_controller(struct spdk_jsonrpc_request *request,
			    const struct spdk_json_val *params)
@@ -349,6 +356,21 @@ rpc_vhost_delete_controller(struct spdk_jsonrpc_request *request,

	rc = spdk_vhost_dev_remove(vdev);
	if (rc < 0) {
		if (rc == -EBUSY) {
			struct vhost_delete_ctrlr_context *ctx;

			ctx = calloc(1, sizeof(*ctx));
			if (ctx == NULL) {
				SPDK_ERRLOG("Failed to allocate memory for vhost_delete_ctrlr context\n");
				rc = -ENOMEM;
				goto invalid;
			}
			ctx->request = request;
			ctx->params = params;
			spdk_thread_send_msg(spdk_get_thread(), _rpc_vhost_delete_controller, ctx);
			free_rpc_delete_vhost_ctrlr(&req);
			return;
		}
		goto invalid;
	}

@@ -365,6 +387,14 @@ invalid:
}
SPDK_RPC_REGISTER("vhost_delete_controller", rpc_vhost_delete_controller, SPDK_RPC_RUNTIME)

static void _rpc_vhost_delete_controller(void *arg)
{
	struct vhost_delete_ctrlr_context *ctx = arg;

	rpc_vhost_delete_controller(ctx->request, ctx->params);
	free(ctx);
}

struct rpc_get_vhost_ctrlrs {
	char *name;
};