From nobody Mon Feb 9 08:28:22 2026 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 F00DA236436 for ; Wed, 26 Feb 2025 18:46:04 +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=1740595565; cv=none; b=WjjF6LPZwbueu8Hn+ASnAUaSZ8clfqhMd2tFhQjdhrUbHqlyzqb+SnHkKQ8aBxQShw3Dq7vC+gF4nZoi4HUH+BKP2OJUJWWYMtDVa+POnD2Ysd8Cpc5i43jwZ1zOXAE+OODty1+xZVA2xk+JFpOBjcIKnVVJrfn0uAk7wx6Zb1w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740595565; c=relaxed/simple; bh=FE28cHM2Xu+6IwRPzQpF/Y9BjWJU8LBOSYm56nzMorc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=r0WGFZfb7yDoQ1nrFIn8gikq6XaBpB3XGcu8hNDsF4pU0gPC7JIguHDtENF+4Wlgbrqgz45+syKfOdGkBa2zbcXVgcoesDBtDlD7KPPiGUKg/CYr4kiBgqSwxGnD1NzNQHlxm7FA/P6tOhamYo0Xqen8kY77Hur9hKpLKaO3HQ0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LHSb4t8W; 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="LHSb4t8W" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1380DC4CED6; Wed, 26 Feb 2025 18:46:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1740595564; bh=FE28cHM2Xu+6IwRPzQpF/Y9BjWJU8LBOSYm56nzMorc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=LHSb4t8WjHOe36CjKcO4O8TgvN3XrISVlK3/CrJH1N++dPJKNjBlGGu7LO0cQ/eRU BsAe+XJWUk1GORxjKthDQ+iHO1uxT8ZfYonEtkziW3IrhbBLfcZYk1JEs5Atf5wIuH Oj1yEX6/fF8DNrZ3Nosk0hT7L+3E/hTBgh+jgR/0tx9qk/sG6eHgY9yd3P7jwat94J fD2FlMy2uqAwONvzEcZOxLL2lPxUFtp8UVR/Hr5Ht1QldylfATd2h06BC+5PHaiCSz U603RnIaK+cJ4xuLTsDpn3dkVtpPib5h88OmfPiIKSrqBjxADZmwnUwwoAvyIe7wWz fhCmRkY59oXDA== From: Daniel Wagner Date: Wed, 26 Feb 2025 19:45:55 +0100 Subject: [PATCH 03/11] nvmet-fcloop: refactor fcloop_nport_alloc 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: <20250226-nvmet-fcloop-v1-3-c0bd83d43e6a@kernel.org> References: <20250226-nvmet-fcloop-v1-0-c0bd83d43e6a@kernel.org> In-Reply-To: <20250226-nvmet-fcloop-v1-0-c0bd83d43e6a@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 There are many different operations done under the spin lock. Since the lport and nport are ref counted it's possible to only use for the list insert and lookup the spin lock. This allows us to untangle the setup steps into a more linear form which reduces the complexity of the functions. Signed-off-by: Daniel Wagner Reviewed-by: Christoph Hellwig --- drivers/nvme/target/fcloop.c | 156 +++++++++++++++++++++++----------------= ---- 1 file changed, 84 insertions(+), 72 deletions(-) diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c index ca46830d46ecbaae21f3ee3e69aa7d52905abcae..de1963c34bd88d0335f70de5695= 65740fd395a0a 100644 --- a/drivers/nvme/target/fcloop.c +++ b/drivers/nvme/target/fcloop.c @@ -1038,6 +1038,8 @@ fcloop_nport_free(struct kref *ref) list_del(&nport->nport_list); spin_unlock_irqrestore(&fcloop_lock, flags); =20 + if (nport->lport) + fcloop_lport_put(nport->lport); kfree(nport); } =20 @@ -1206,33 +1208,63 @@ __wait_localport_unreg(struct fcloop_lport *lport) return ret; } =20 +static struct fcloop_lport * +fcloop_lport_lookup(u64 node_name, u64 port_name) +{ + struct fcloop_lport *lp, *lport =3D NULL; + unsigned long flags; + + spin_lock_irqsave(&fcloop_lock, flags); + list_for_each_entry(lp, &fcloop_lports, lport_list) { + if (lp->localport->node_name !=3D node_name || + lp->localport->port_name !=3D port_name) + continue; + + if (fcloop_lport_get(lp)) + lport =3D lp; + + break; + } + spin_unlock_irqrestore(&fcloop_lock, flags); + + return lport; +} + +static struct fcloop_nport * +fcloop_nport_lookup(u64 node_name, u64 port_name) +{ + struct fcloop_nport *np, *nport =3D NULL; + unsigned long flags; + + spin_lock_irqsave(&fcloop_lock, flags); + list_for_each_entry(np, &fcloop_nports, nport_list) { + if (np->node_name !=3D node_name || + np->port_name !=3D port_name) + continue; + + if (fcloop_nport_get(np)) + nport =3D np; + + break; + } + spin_unlock_irqrestore(&fcloop_lock, flags); + + return nport; +} =20 static ssize_t fcloop_delete_local_port(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct fcloop_lport *tlport, *lport =3D NULL; + struct fcloop_lport *lport; u64 nodename, portname; - unsigned long flags; int ret; =20 ret =3D fcloop_parse_nm_options(dev, &nodename, &portname, buf); if (ret) return ret; =20 - spin_lock_irqsave(&fcloop_lock, flags); - - list_for_each_entry(tlport, &fcloop_lports, lport_list) { - if (tlport->localport->node_name =3D=3D nodename && - tlport->localport->port_name =3D=3D portname) { - if (!fcloop_lport_get(tlport)) - break; - lport =3D tlport; - break; - } - } - spin_unlock_irqrestore(&fcloop_lock, flags); - + lport =3D fcloop_lport_lookup(nodename, portname); if (!lport) return -ENOENT; =20 @@ -1245,9 +1277,9 @@ fcloop_delete_local_port(struct device *dev, struct d= evice_attribute *attr, static struct fcloop_nport * fcloop_alloc_nport(const char *buf, size_t count, bool remoteport) { - struct fcloop_nport *newnport, *nport =3D NULL; - struct fcloop_lport *tmplport, *lport =3D NULL; struct fcloop_ctrl_options *opts; + struct fcloop_nport *nport; + struct fcloop_lport *lport; unsigned long flags; u32 opts_mask =3D (remoteport) ? RPORT_OPTS : TGTPORT_OPTS; int ret; @@ -1261,79 +1293,59 @@ fcloop_alloc_nport(const char *buf, size_t count, b= ool remoteport) goto out_free_opts; =20 /* everything there ? */ - if ((opts->mask & opts_mask) !=3D opts_mask) { - ret =3D -EINVAL; + if ((opts->mask & opts_mask) !=3D opts_mask) goto out_free_opts; - } =20 - newnport =3D kzalloc(sizeof(*newnport), GFP_KERNEL); - if (!newnport) + lport =3D fcloop_lport_lookup(opts->wwnn, opts->wwpn); + if (lport) { + /* invalid configuration */ + fcloop_lport_put(lport); goto out_free_opts; + } =20 - INIT_LIST_HEAD(&newnport->nport_list); - newnport->node_name =3D opts->wwnn; - newnport->port_name =3D opts->wwpn; - if (opts->mask & NVMF_OPT_ROLES) - newnport->port_role =3D opts->roles; - if (opts->mask & NVMF_OPT_FCADDR) - newnport->port_id =3D opts->fcaddr; - kref_init(&newnport->ref); + nport =3D fcloop_nport_lookup(opts->wwnn, opts->wwpn); + if (nport && ((remoteport && nport->rport) || + (!remoteport && nport->tport))) { + /* invalid configuration */ + goto out_put_nport; + } =20 - spin_lock_irqsave(&fcloop_lock, flags); + if (!nport) { + nport =3D kzalloc(sizeof(*nport), GFP_KERNEL); + if (!nport) + goto out_free_opts; =20 - list_for_each_entry(tmplport, &fcloop_lports, lport_list) { - if (tmplport->localport->node_name =3D=3D opts->wwnn && - tmplport->localport->port_name =3D=3D opts->wwpn) - goto out_invalid_opts; + INIT_LIST_HEAD(&nport->nport_list); + nport->node_name =3D opts->wwnn; + nport->port_name =3D opts->wwpn; + kref_init(&nport->ref); =20 - if (tmplport->localport->node_name =3D=3D opts->lpwwnn && - tmplport->localport->port_name =3D=3D opts->lpwwpn) - lport =3D tmplport; + spin_lock_irqsave(&fcloop_lock, flags); + list_add_tail(&nport->nport_list, &fcloop_nports); + spin_unlock_irqrestore(&fcloop_lock, flags); } =20 + if (opts->mask & NVMF_OPT_ROLES) + nport->port_role =3D opts->roles; + if (opts->mask & NVMF_OPT_FCADDR) + nport->port_id =3D opts->fcaddr; + if (remoteport) { + lport =3D fcloop_lport_lookup(opts->lpwwnn, opts->lpwwpn); if (!lport) - goto out_invalid_opts; - newnport->lport =3D lport; - } - - list_for_each_entry(nport, &fcloop_nports, nport_list) { - if (nport->node_name =3D=3D opts->wwnn && - nport->port_name =3D=3D opts->wwpn) { - if ((remoteport && nport->rport) || - (!remoteport && nport->tport)) { - nport =3D NULL; - goto out_invalid_opts; - } - - fcloop_nport_get(nport); + goto out_put_nport; =20 - spin_unlock_irqrestore(&fcloop_lock, flags); - - if (remoteport) - nport->lport =3D lport; - if (opts->mask & NVMF_OPT_ROLES) - nport->port_role =3D opts->roles; - if (opts->mask & NVMF_OPT_FCADDR) - nport->port_id =3D opts->fcaddr; - goto out_free_newnport; - } + nport->lport =3D lport; } =20 - list_add_tail(&newnport->nport_list, &fcloop_nports); - - spin_unlock_irqrestore(&fcloop_lock, flags); - kfree(opts); - return newnport; + return nport; =20 -out_invalid_opts: - spin_unlock_irqrestore(&fcloop_lock, flags); -out_free_newnport: - kfree(newnport); +out_put_nport: + fcloop_nport_put(nport); out_free_opts: kfree(opts); - return nport; + return NULL; } =20 static ssize_t --=20 2.48.1