Commit 891cdbb1 authored by Daniel Wagner's avatar Daniel Wagner Committed by Keith Busch
Browse files

nvme-fc: use lock accessing port_state and rport state



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: default avatarShinichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Closes: https://lore.kernel.org/all/u4ttvhnn7lark5w3sgrbuy2rxupcvosp4qmvj46nwzgeo5ausc@uyrkdls2muwx


Signed-off-by: default avatarDaniel Wagner <wagi@kernel.org>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarKeith Busch <kbusch@kernel.org>
parent 10c165af
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -3032,11 +3032,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 "