Commit 0d98a949 authored by Naresh Gottumukkala's avatar Naresh Gottumukkala Committed by Tomasz Zawadzki
Browse files

nvmf: Allow asynchronous nvmf transport destroy.



As part of FC transport destroy, FC LLD (Low level Driver) needs to
to do its cleanup which cannot be completed synchronously. So
allow transport destroy to be asynchronous.

FC transport code to use this functionality will be pushed shortly.

Signed-off-by: default avatarNaresh Gottumukkala <raju.gottumukkala@broadcom.com>
Change-Id: I104cf7d131e18199abdcf0651df261fe41d666ef
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5180


Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent d4ad1f9c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -4,8 +4,8 @@

### nvmf

The function `qpair_fini` in the transport interface now accepts a cb_fn and
cb_arg to call upon completion, and its execution can be asynchronous.
The functions `destroy` and `qpair_fini` in the transport interface now accept a
cb_fn and cb_arg to call upon completion, and their execution can be asynchronous.

The SPDK nvmf target now supports async event notification for discovery log changes.
This allows the initiator to create persistent connection to discovery controller and
+6 −1
Original line number Diff line number Diff line
@@ -926,14 +926,19 @@ spdk_nvmf_transport_opts_init(const char *transport_name,
struct spdk_nvmf_transport *spdk_nvmf_transport_create(const char *transport_name,
		struct spdk_nvmf_transport_opts *opts);

typedef void (*spdk_nvmf_transport_destroy_done_cb)(void *cb_arg);

/**
 * Destroy a protocol transport
 *
 * \param transport The transport to destory
 * \param cb_fn A callback that will be called once the transport is destroyed
 * \param cb_arg A context argument passed to cb_fn.
 *
 * \return 0 on success, -1 on failure.
 */
int spdk_nvmf_transport_destroy(struct spdk_nvmf_transport *transport);
int spdk_nvmf_transport_destroy(struct spdk_nvmf_transport *transport,
				spdk_nvmf_transport_destroy_done_cb cb_fn, void *cb_arg);

/**
 * Get an existing transport from the target
+2 −1
Original line number Diff line number Diff line
@@ -235,7 +235,8 @@ struct spdk_nvmf_transport_ops {
	/**
	 * Destroy the transport
	 */
	int (*destroy)(struct spdk_nvmf_transport *transport);
	int (*destroy)(struct spdk_nvmf_transport *transport,
		       spdk_nvmf_transport_destroy_done_cb cb_fn, void *cb_arg);

	/**
	  * Instruct the transport to accept new connections at the address
+5 −1
Original line number Diff line number Diff line
@@ -1861,7 +1861,8 @@ nvmf_fc_create(struct spdk_nvmf_transport_opts *opts)
}

static int
nvmf_fc_destroy(struct spdk_nvmf_transport *transport)
nvmf_fc_destroy(struct spdk_nvmf_transport *transport,
		spdk_nvmf_transport_destroy_done_cb cb_fn, void *cb_arg)
{
	if (transport) {
		struct spdk_nvmf_fc_transport *ftransport;
@@ -1884,6 +1885,9 @@ nvmf_fc_destroy(struct spdk_nvmf_transport *transport)
		nvmf_fc_port_cleanup();
	}

	if (cb_fn) {
		cb_fn(cb_arg);
	}
	return 0;
}

+24 −17
Original line number Diff line number Diff line
@@ -313,13 +313,33 @@ spdk_nvmf_tgt_create(struct spdk_nvmf_target_opts *opts)
	return tgt;
}

static void
_nvmf_tgt_destroy_next_transport(void *ctx)
{
	struct spdk_nvmf_tgt *tgt = ctx;
	struct spdk_nvmf_transport *transport;

	if (!TAILQ_EMPTY(&tgt->transports)) {
		transport = TAILQ_FIRST(&tgt->transports);
		TAILQ_REMOVE(&tgt->transports, transport, link);
		spdk_nvmf_transport_destroy(transport, _nvmf_tgt_destroy_next_transport, tgt);
	} else {
		spdk_nvmf_tgt_destroy_done_fn *destroy_cb_fn = tgt->destroy_cb_fn;
		void *destroy_cb_arg = tgt->destroy_cb_arg;

		pthread_mutex_destroy(&tgt->mutex);
		free(tgt);

		if (destroy_cb_fn) {
			destroy_cb_fn(destroy_cb_arg, 0);
		}
	}
}

static void
nvmf_tgt_destroy_cb(void *io_device)
{
	struct spdk_nvmf_tgt *tgt = io_device;
	struct spdk_nvmf_transport *transport, *transport_tmp;
	spdk_nvmf_tgt_destroy_done_fn		*destroy_cb_fn;
	void					*destroy_cb_arg;
	uint32_t i;

	if (tgt->subsystems) {
@@ -332,20 +352,7 @@ nvmf_tgt_destroy_cb(void *io_device)
		free(tgt->subsystems);
	}

	TAILQ_FOREACH_SAFE(transport, &tgt->transports, link, transport_tmp) {
		TAILQ_REMOVE(&tgt->transports, transport, link);
		spdk_nvmf_transport_destroy(transport);
	}

	destroy_cb_fn = tgt->destroy_cb_fn;
	destroy_cb_arg = tgt->destroy_cb_arg;

	pthread_mutex_destroy(&tgt->mutex);
	free(tgt);

	if (destroy_cb_fn) {
		destroy_cb_fn(destroy_cb_arg, 0);
	}
	_nvmf_tgt_destroy_next_transport(tgt);
}

void
Loading