]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
nvme-fc: use lock accessing port_state and rport state
authorDaniel Wagner <wagi@kernel.org>
Tue, 2 Sep 2025 10:22:03 +0000 (12:22 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Nov 2025 20:34:06 +0000 (15:34 -0500)
[ Upstream commit 891cdbb162ccdb079cd5228ae43bdeebce8597ad ]

nvme_fc_unregister_remote removes the remote port on a lport object at
any point in time when there is no active association. This races with
with the reconnect logic, because nvme_fc_create_association is not
taking a lock to check the port_state and atomically increase the
active count on the rport.

Reported-by: Shinichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Closes: https://lore.kernel.org/all/u4ttvhnn7lark5w3sgrbuy2rxupcvosp4qmvj46nwzgeo5ausc@uyrkdls2muwx
Signed-off-by: Daniel Wagner <wagi@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/nvme/host/fc.c

index 7c13a400071e651c445a41d795bd11b2a4c2c9d8..57c94912338608f2b3218bbe8044c8252ea2d9d9 100644 (file)
@@ -3026,11 +3026,17 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
 
        ++ctrl->ctrl.nr_reconnects;
 
-       if (ctrl->rport->remoteport.port_state != FC_OBJSTATE_ONLINE)
+       spin_lock_irqsave(&ctrl->rport->lock, flags);
+       if (ctrl->rport->remoteport.port_state != FC_OBJSTATE_ONLINE) {
+               spin_unlock_irqrestore(&ctrl->rport->lock, flags);
                return -ENODEV;
+       }
 
-       if (nvme_fc_ctlr_active_on_rport(ctrl))
+       if (nvme_fc_ctlr_active_on_rport(ctrl)) {
+               spin_unlock_irqrestore(&ctrl->rport->lock, flags);
                return -ENOTUNIQ;
+       }
+       spin_unlock_irqrestore(&ctrl->rport->lock, flags);
 
        dev_info(ctrl->ctrl.device,
                "NVME-FC{%d}: create association : host wwpn 0x%016llx "