Commit 8a1ad5a2 authored by John Levon's avatar John Levon Committed by Tomasz Zawadzki
Browse files

nvmf/vfio-user: correct accept poller lifetime



The accept poller only needs to run when vfu_attach_ctx() makes sense:
in other words, when we don't have a controller created.

Signed-off-by: default avatarJohn Levon <john.levon@nutanix.com>
Change-Id: Icef4e6184c9ae6d7951d015530a05132c4ba6994
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10720


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
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 avatarShuhei Matsumoto <smatsumoto@nvidia.com>
parent e334bba9
Loading
Loading
Loading
Loading
+66 −11
Original line number Diff line number Diff line
@@ -355,6 +355,7 @@ struct nvmf_vfio_user_endpoint {
	struct nvmf_vfio_user_transport		*transport;
	vfu_ctx_t				*vfu_ctx;
	struct spdk_poller			*accept_poller;
	struct spdk_thread			*accept_thread;
	struct msixcap				*msix;
	vfu_pci_config_space_t			*pci_config_space;
	int					devmem_fd;
@@ -3031,6 +3032,42 @@ vfio_user_dev_info_fill(struct nvmf_vfio_user_transport *vu_transport,
	return 0;
}

static int nvmf_vfio_user_accept(void *ctx);

/*
 * Register an "accept" poller: this is polling for incoming vfio-user socket
 * connections (on the listening socket).
 *
 * We need to do this on first listening, and also after destroying a
 * controller, so we can accept another connection.
 */
static int
vfio_user_register_accept_poller(struct nvmf_vfio_user_endpoint *endpoint)
{
	uint64_t poll_rate_us = endpoint->transport->transport.opts.acceptor_poll_rate;

	SPDK_DEBUGLOG(nvmf_vfio, "registering accept poller\n");

	endpoint->accept_poller = SPDK_POLLER_REGISTER(nvmf_vfio_user_accept,
				  endpoint, poll_rate_us);

	if (!endpoint->accept_poller) {
		return -1;
	}

	endpoint->accept_thread = spdk_get_thread();

	return 0;
}

static void
_vfio_user_relisten(void *ctx)
{
	struct nvmf_vfio_user_endpoint *endpoint = ctx;

	vfio_user_register_accept_poller(endpoint);
}

static void
_free_ctrlr(void *ctx)
{
@@ -3038,10 +3075,18 @@ _free_ctrlr(void *ctx)
	struct nvmf_vfio_user_endpoint *endpoint = ctrlr->endpoint;

	spdk_poller_unregister(&ctrlr->vfu_ctx_poller);

	free(ctrlr);

	if (endpoint && endpoint->need_async_destroy) {
	if (endpoint == NULL) {
		return;
	}

	if (endpoint->need_async_destroy) {
		nvmf_vfio_user_destroy_endpoint(endpoint);
	} else {
		spdk_thread_send_msg(endpoint->accept_thread,
				     _vfio_user_relisten, endpoint);
	}
}

@@ -3064,7 +3109,7 @@ free_ctrlr(struct nvmf_vfio_user_ctrlr *ctrlr)
	}
}

static void
static int
nvmf_vfio_user_create_ctrlr(struct nvmf_vfio_user_transport *transport,
			    struct nvmf_vfio_user_endpoint *endpoint)
{
@@ -3114,10 +3159,9 @@ out:
		SPDK_ERRLOG("%s: failed to create vfio-user controller: %s\n",
			    endpoint_id(endpoint), strerror(-err));
	}
}

static int
nvmf_vfio_user_accept(void *ctx);
	return err;
}

static int
nvmf_vfio_user_listen(struct spdk_nvmf_transport *transport,
@@ -3239,11 +3283,9 @@ nvmf_vfio_user_listen(struct spdk_nvmf_transport *transport,
		goto out;
	}

	endpoint->accept_poller = SPDK_POLLER_REGISTER(nvmf_vfio_user_accept,
				  endpoint,
				  vu_transport->transport.opts.acceptor_poll_rate);
	if (!endpoint->accept_poller) {
		ret = -1;
	ret = vfio_user_register_accept_poller(endpoint);

	if (ret != 0) {
		goto out;
	}

@@ -3368,7 +3410,20 @@ nvmf_vfio_user_accept(void *ctx)
	err = vfu_attach_ctx(endpoint->vfu_ctx);

	if (err == 0) {
		nvmf_vfio_user_create_ctrlr(vu_transport, endpoint);
		SPDK_DEBUGLOG(nvmf_vfio, "attach succeeded\n");

		err = nvmf_vfio_user_create_ctrlr(vu_transport, endpoint);

		if (err == 0) {
			/*
			 * Unregister ourselves: now we've accepted a
			 * connection, there is nothing for us to poll for, and
			 * we will poll the connection via vfu_run_ctx()
			 * instead.
			 */
			spdk_poller_unregister(&endpoint->accept_poller);
		}

		return SPDK_POLLER_BUSY;
	}