Commit e1d1695c authored by Jacek Kalwas's avatar Jacek Kalwas Committed by Jim Harris
Browse files

nvmf: check if listener already exists in subsystem earlier



It fixes memory leak e.g. when add_listener rpc called twice with the
same trid on the same subsystem (ref = 2). In such case kill or
remove_listener decrements ref only once.

Signed-off-by: default avatarJacek Kalwas <jacek.kalwas@intel.com>
Change-Id: Ib19f2e50838feff1c9108957ee82a42da66e54a2
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/482446


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: default avatarAlexey Marchuk <alexeymar@mellanox.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent bad8847f
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -447,6 +447,9 @@ void spdk_nvmf_subsystem_remove_all_listeners(struct spdk_nvmf_subsystem *subsys
		bool stop);
struct spdk_nvmf_ctrlr *spdk_nvmf_subsystem_get_ctrlr(struct spdk_nvmf_subsystem *subsystem,
		uint16_t cntlid);
struct spdk_nvmf_listener *spdk_nvmf_subsystem_find_listener(struct spdk_nvmf_subsystem *subsystem,
		const struct spdk_nvme_transport_id *trid);

int spdk_nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr);
void spdk_nvmf_ctrlr_async_event_reservation_notification(struct spdk_nvmf_ctrlr *ctrlr);
void spdk_nvmf_ns_reservation_request(void *ctx);
+4 −2
Original line number Diff line number Diff line
@@ -655,8 +655,10 @@ nvmf_rpc_listen_paused(struct spdk_nvmf_subsystem *subsystem,
	struct nvmf_rpc_listener_ctx *ctx = cb_arg;

	if (ctx->op == NVMF_RPC_LISTEN_ADD) {
		if (!spdk_nvmf_subsystem_find_listener(subsystem, &ctx->trid)) {
			spdk_nvmf_tgt_listen(ctx->tgt, &ctx->trid, nvmf_rpc_tgt_listen, ctx);
			return;
		}
	} else if (ctx->op == NVMF_RPC_LISTEN_REMOVE) {
		if (spdk_nvmf_subsystem_remove_listener(subsystem, &ctx->trid)) {
			SPDK_ERRLOG("Unable to remove listener.\n");
+5 −5
Original line number Diff line number Diff line
@@ -732,8 +732,8 @@ spdk_nvmf_host_get_nqn(struct spdk_nvmf_host *host)
	return host->nqn;
}

static struct spdk_nvmf_listener *
_spdk_nvmf_subsystem_find_listener(struct spdk_nvmf_subsystem *subsystem,
struct spdk_nvmf_listener *
spdk_nvmf_subsystem_find_listener(struct spdk_nvmf_subsystem *subsystem,
				  const struct spdk_nvme_transport_id *trid)
{
	struct spdk_nvmf_listener *listener;
@@ -759,7 +759,7 @@ spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem,
		return -EAGAIN;
	}

	if (_spdk_nvmf_subsystem_find_listener(subsystem, trid)) {
	if (spdk_nvmf_subsystem_find_listener(subsystem, trid)) {
		/* Listener already exists in this subsystem */
		return 0;
	}
@@ -795,7 +795,7 @@ spdk_nvmf_subsystem_remove_listener(struct spdk_nvmf_subsystem *subsystem,
		return -EAGAIN;
	}

	listener = _spdk_nvmf_subsystem_find_listener(subsystem, trid);
	listener = spdk_nvmf_subsystem_find_listener(subsystem, trid);
	if (listener == NULL) {
		return -ENOENT;
	}