From nobody Tue Dec 16 07:07:00 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E09CA1DF755 for ; Wed, 7 May 2025 12:23:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746620586; cv=none; b=d7uThpq72bdzp/JIT40yL0jkMs6g7Ba0srOUVXSw3wsyVzeBbsopdPhndDM9FgZgeY9N8EkMs7xLNonVFO/oL824UD/pYkbSUslDkIwvflrRriUsM6GhqK3G+S7/Kyz1zLCs/V0dCdryFBPHZIGn+WEAXdfun6XUIJ1XNTgIvZo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746620586; c=relaxed/simple; bh=jEKbG5pfx1l0nP/U7lRUSa0XqnGWbsgWmnMw8er6V34=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=vCpqz13sUKbNxppNLfEAttqZa+Cav+kbT7uI+3CmxMEk4F+yZUUD9NIksOdW2+iDjRPdOWjsflVSHNA1Sf0BRtEravB5qo+8kAAtXv7oKenzPwTlQer1PMOZWYcQhIFH6dH2Pjg5xq+5q6BkMKdCzeXQRtcNbf3EhXTESbsFvfw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JDVYH5OS; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JDVYH5OS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F027DC4CEEB; Wed, 7 May 2025 12:23:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746620585; bh=jEKbG5pfx1l0nP/U7lRUSa0XqnGWbsgWmnMw8er6V34=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JDVYH5OSvHrHuHWyeu4oC6KasDrRjMjAHTjM5s2tW+q3xjpCWjaz5JBb5fARtu6To f+3enFNz4pbSye06rxYGULNcYFuC0JnNxWHMLD3F284fXnq7ZIW+0MYR/7DWhXTm0X 1d4TwlT9WY9zNGXKPZKksacH5JSFd1/ihXVbOYnvHrTQXJcBhNqPpC+MjAjI9pNn2f 1HwETJJjUaR+M4ngAaNJetvrhMi7mE5xAND4scBlZLb4LtWtjDCIfGoNIEE4fg4yMk oRDR9op8Oa2CKEE0AFeb3dtZKYJTiYIPPpsrRKW9OG12q4hicYBV+Hi+WmWgNlKiLI vuHdB+UvNlvBQ== From: Daniel Wagner Date: Wed, 07 May 2025 14:22:57 +0200 Subject: [PATCH v6 01/14] nvmet-fcloop: track ref counts for nports Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250507-nvmet-fcloop-v6-1-ca02e16fb018@kernel.org> References: <20250507-nvmet-fcloop-v6-0-ca02e16fb018@kernel.org> In-Reply-To: <20250507-nvmet-fcloop-v6-0-ca02e16fb018@kernel.org> To: James Smart , Christoph Hellwig , Sagi Grimberg , Chaitanya Kulkarni Cc: Hannes Reinecke , Keith Busch , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Daniel Wagner X-Mailer: b4 0.14.2 A nport object is always used in association with targerport, remoteport, tport and rport objects. Add explicit references for any of the associated object. This ensures that nport is not removed too early on shutdown sequences. Signed-off-by: Daniel Wagner --- drivers/nvme/target/fcloop.c | 133 +++++++++++++++++++++++++++++----------= ---- 1 file changed, 90 insertions(+), 43 deletions(-) diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c index 641201e62c1bafa13986642c6c4067b35f784edd..2b23e43ef4403fa4d70c66263f7= 750165d2ddc72 100644 --- a/drivers/nvme/target/fcloop.c +++ b/drivers/nvme/target/fcloop.c @@ -1047,8 +1047,14 @@ static void fcloop_remoteport_delete(struct nvme_fc_remote_port *remoteport) { struct fcloop_rport *rport =3D remoteport->private; + unsigned long flags; =20 flush_work(&rport->ls_work); + + spin_lock_irqsave(&fcloop_lock, flags); + rport->nport->rport =3D NULL; + spin_unlock_irqrestore(&fcloop_lock, flags); + fcloop_nport_put(rport->nport); } =20 @@ -1056,8 +1062,14 @@ static void fcloop_targetport_delete(struct nvmet_fc_target_port *targetport) { struct fcloop_tport *tport =3D targetport->private; + unsigned long flags; =20 flush_work(&tport->ls_work); + + spin_lock_irqsave(&fcloop_lock, flags); + tport->nport->tport =3D NULL; + spin_unlock_irqrestore(&fcloop_lock, flags); + fcloop_nport_put(tport->nport); } =20 @@ -1184,6 +1196,37 @@ __wait_localport_unreg(struct fcloop_lport *lport) return ret; } =20 +static struct fcloop_nport * +__fcloop_nport_lookup(u64 node_name, u64 port_name) +{ + struct fcloop_nport *nport; + + list_for_each_entry(nport, &fcloop_nports, nport_list) { + if (nport->node_name !=3D node_name || + nport->port_name !=3D port_name) + continue; + + if (fcloop_nport_get(nport)) + return nport; + + break; + } + + return NULL; +} + +static struct fcloop_nport * +fcloop_nport_lookup(u64 node_name, u64 port_name) +{ + struct fcloop_nport *nport; + unsigned long flags; + + spin_lock_irqsave(&fcloop_lock, flags); + nport =3D __fcloop_nport_lookup(node_name, port_name); + spin_unlock_irqrestore(&fcloop_lock, flags); + + return nport; +} =20 static ssize_t fcloop_delete_local_port(struct device *dev, struct device_attribute *attr, @@ -1365,6 +1408,8 @@ __unlink_remote_port(struct fcloop_nport *nport) { struct fcloop_rport *rport =3D nport->rport; =20 + lockdep_assert_held(&fcloop_lock); + if (rport && nport->tport) nport->tport->remoteport =3D NULL; nport->rport =3D NULL; @@ -1377,9 +1422,6 @@ __unlink_remote_port(struct fcloop_nport *nport) static int __remoteport_unreg(struct fcloop_nport *nport, struct fcloop_rport *rport) { - if (!rport) - return -EALREADY; - return nvme_fc_unregister_remoteport(rport->remoteport); } =20 @@ -1387,8 +1429,8 @@ static ssize_t fcloop_delete_remote_port(struct device *dev, struct device_attribute *att= r, const char *buf, size_t count) { - struct fcloop_nport *nport =3D NULL, *tmpport; - static struct fcloop_rport *rport; + struct fcloop_nport *nport; + struct fcloop_rport *rport; u64 nodename, portname; unsigned long flags; int ret; @@ -1397,24 +1439,24 @@ fcloop_delete_remote_port(struct device *dev, struc= t device_attribute *attr, if (ret) return ret; =20 - spin_lock_irqsave(&fcloop_lock, flags); - - list_for_each_entry(tmpport, &fcloop_nports, nport_list) { - if (tmpport->node_name =3D=3D nodename && - tmpport->port_name =3D=3D portname && tmpport->rport) { - nport =3D tmpport; - rport =3D __unlink_remote_port(nport); - break; - } - } + nport =3D fcloop_nport_lookup(nodename, portname); + if (!nport) + return -ENOENT; =20 + spin_lock_irqsave(&fcloop_lock, flags); + rport =3D __unlink_remote_port(nport); spin_unlock_irqrestore(&fcloop_lock, flags); =20 - if (!nport) - return -ENOENT; + if (!rport) { + ret =3D -ENOENT; + goto out_nport_put; + } =20 ret =3D __remoteport_unreg(nport, rport); =20 +out_nport_put: + fcloop_nport_put(nport); + return ret ? ret : count; } =20 @@ -1465,6 +1507,8 @@ __unlink_target_port(struct fcloop_nport *nport) { struct fcloop_tport *tport =3D nport->tport; =20 + lockdep_assert_held(&fcloop_lock); + if (tport && nport->rport) nport->rport->targetport =3D NULL; nport->tport =3D NULL; @@ -1475,9 +1519,6 @@ __unlink_target_port(struct fcloop_nport *nport) static int __targetport_unreg(struct fcloop_nport *nport, struct fcloop_tport *tport) { - if (!tport) - return -EALREADY; - return nvmet_fc_unregister_targetport(tport->targetport); } =20 @@ -1485,8 +1526,8 @@ static ssize_t fcloop_delete_target_port(struct device *dev, struct device_attribute *att= r, const char *buf, size_t count) { - struct fcloop_nport *nport =3D NULL, *tmpport; - struct fcloop_tport *tport =3D NULL; + struct fcloop_nport *nport; + struct fcloop_tport *tport; u64 nodename, portname; unsigned long flags; int ret; @@ -1495,24 +1536,24 @@ fcloop_delete_target_port(struct device *dev, struc= t device_attribute *attr, if (ret) return ret; =20 - spin_lock_irqsave(&fcloop_lock, flags); - - list_for_each_entry(tmpport, &fcloop_nports, nport_list) { - if (tmpport->node_name =3D=3D nodename && - tmpport->port_name =3D=3D portname && tmpport->tport) { - nport =3D tmpport; - tport =3D __unlink_target_port(nport); - break; - } - } + nport =3D fcloop_nport_lookup(nodename, portname); + if (!nport) + return -ENOENT; =20 + spin_lock_irqsave(&fcloop_lock, flags); + tport =3D __unlink_target_port(nport); spin_unlock_irqrestore(&fcloop_lock, flags); =20 - if (!nport) - return -ENOENT; + if (!tport) { + ret =3D -ENOENT; + goto out_nport_put; + } =20 ret =3D __targetport_unreg(nport, tport); =20 +out_nport_put: + fcloop_nport_put(nport); + return ret ? ret : count; } =20 @@ -1609,8 +1650,8 @@ static int __init fcloop_init(void) =20 static void __exit fcloop_exit(void) { - struct fcloop_lport *lport =3D NULL; - struct fcloop_nport *nport =3D NULL; + struct fcloop_lport *lport; + struct fcloop_nport *nport; struct fcloop_tport *tport; struct fcloop_rport *rport; unsigned long flags; @@ -1621,7 +1662,7 @@ static void __exit fcloop_exit(void) for (;;) { nport =3D list_first_entry_or_null(&fcloop_nports, typeof(*nport), nport_list); - if (!nport) + if (!nport || !fcloop_nport_get(nport)) break; =20 tport =3D __unlink_target_port(nport); @@ -1629,13 +1670,19 @@ static void __exit fcloop_exit(void) =20 spin_unlock_irqrestore(&fcloop_lock, flags); =20 - ret =3D __targetport_unreg(nport, tport); - if (ret) - pr_warn("%s: Failed deleting target port\n", __func__); + if (tport) { + ret =3D __targetport_unreg(nport, tport); + if (ret) + pr_warn("%s: Failed deleting target port\n", __func__); + } =20 - ret =3D __remoteport_unreg(nport, rport); - if (ret) - pr_warn("%s: Failed deleting remote port\n", __func__); + if (rport) { + ret =3D __remoteport_unreg(nport, rport); + if (ret) + pr_warn("%s: Failed deleting remote port\n", __func__); + } + + fcloop_nport_put(nport); =20 spin_lock_irqsave(&fcloop_lock, flags); } --=20 2.49.0