linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH AUTOSEL 4.19 01/34] nvme_fc: add module to ops template to allow module references
@ 2019-12-20 14:34 Sasha Levin
  2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 02/34] nvme-fc: fix double-free scenarios on hw queues Sasha Levin
                   ` (32 more replies)
  0 siblings, 33 replies; 34+ messages in thread
From: Sasha Levin @ 2019-12-20 14:34 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: James Smart, Himanshu Madhani, Christoph Hellwig, Keith Busch,
	Sasha Levin, linux-nvme, linux-scsi

From: James Smart <jsmart2021@gmail.com>

[ Upstream commit 863fbae929c7a5b64e96b8a3ffb34a29eefb9f8f ]

In nvme-fc: it's possible to have connected active controllers
and as no references are taken on the LLDD, the LLDD can be
unloaded.  The controller would enter a reconnect state and as
long as the LLDD resumed within the reconnect timeout, the
controller would resume.  But if a namespace on the controller
is the root device, allowing the driver to unload can be problematic.
To reload the driver, it may require new io to the boot device,
and as it's no longer connected we get into a catch-22 that
eventually fails, and the system locks up.

Fix this issue by taking a module reference for every connected
controller (which is what the core layer did to the transport
module). Reference is cleared when the controller is removed.

Acked-by: Himanshu Madhani <hmadhani@marvell.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/nvme/host/fc.c          | 14 ++++++++++++--
 drivers/nvme/target/fcloop.c    |  1 +
 drivers/scsi/lpfc/lpfc_nvme.c   |  2 ++
 drivers/scsi/qla2xxx/qla_nvme.c |  1 +
 include/linux/nvme-fc-driver.h  |  4 ++++
 5 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index 565bddcfd130d..d567035571bf2 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -342,7 +342,8 @@ nvme_fc_register_localport(struct nvme_fc_port_info *pinfo,
 	    !template->ls_req || !template->fcp_io ||
 	    !template->ls_abort || !template->fcp_abort ||
 	    !template->max_hw_queues || !template->max_sgl_segments ||
-	    !template->max_dif_sgl_segments || !template->dma_boundary) {
+	    !template->max_dif_sgl_segments || !template->dma_boundary ||
+	    !template->module) {
 		ret = -EINVAL;
 		goto out_reghost_failed;
 	}
@@ -1986,6 +1987,7 @@ nvme_fc_ctrl_free(struct kref *ref)
 {
 	struct nvme_fc_ctrl *ctrl =
 		container_of(ref, struct nvme_fc_ctrl, ref);
+	struct nvme_fc_lport *lport = ctrl->lport;
 	unsigned long flags;
 
 	if (ctrl->ctrl.tagset) {
@@ -2011,6 +2013,7 @@ nvme_fc_ctrl_free(struct kref *ref)
 	if (ctrl->ctrl.opts)
 		nvmf_free_options(ctrl->ctrl.opts);
 	kfree(ctrl);
+	module_put(lport->ops->module);
 }
 
 static void
@@ -3040,10 +3043,15 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
 		goto out_fail;
 	}
 
+	if (!try_module_get(lport->ops->module)) {
+		ret = -EUNATCH;
+		goto out_free_ctrl;
+	}
+
 	idx = ida_simple_get(&nvme_fc_ctrl_cnt, 0, 0, GFP_KERNEL);
 	if (idx < 0) {
 		ret = -ENOSPC;
-		goto out_free_ctrl;
+		goto out_mod_put;
 	}
 
 	ctrl->ctrl.opts = opts;
@@ -3185,6 +3193,8 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
 out_free_ida:
 	put_device(ctrl->dev);
 	ida_simple_remove(&nvme_fc_ctrl_cnt, ctrl->cnum);
+out_mod_put:
+	module_put(lport->ops->module);
 out_free_ctrl:
 	kfree(ctrl);
 out_fail:
diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c
index 291f4121f516a..f0536d341f2f2 100644
--- a/drivers/nvme/target/fcloop.c
+++ b/drivers/nvme/target/fcloop.c
@@ -825,6 +825,7 @@ fcloop_targetport_delete(struct nvmet_fc_target_port *targetport)
 #define FCLOOP_DMABOUND_4G		0xFFFFFFFF
 
 static struct nvme_fc_port_template fctemplate = {
+	.module			= THIS_MODULE,
 	.localport_delete	= fcloop_localport_delete,
 	.remoteport_delete	= fcloop_remoteport_delete,
 	.create_queue		= fcloop_create_queue,
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index f73726e55e44d..6c355d87c709d 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -1903,6 +1903,8 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport,
 
 /* Declare and initialization an instance of the FC NVME template. */
 static struct nvme_fc_port_template lpfc_nvme_template = {
+	.module	= THIS_MODULE,
+
 	/* initiator-based functions */
 	.localport_delete  = lpfc_nvme_localport_delete,
 	.remoteport_delete = lpfc_nvme_remoteport_delete,
diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c
index 5590d6e8b5762..db367e428095d 100644
--- a/drivers/scsi/qla2xxx/qla_nvme.c
+++ b/drivers/scsi/qla2xxx/qla_nvme.c
@@ -560,6 +560,7 @@ static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
 }
 
 static struct nvme_fc_port_template qla_nvme_fc_transport = {
+	.module	= THIS_MODULE,
 	.localport_delete = qla_nvme_localport_delete,
 	.remoteport_delete = qla_nvme_remoteport_delete,
 	.create_queue   = qla_nvme_alloc_queue,
diff --git a/include/linux/nvme-fc-driver.h b/include/linux/nvme-fc-driver.h
index 496ff759f84c6..2f3ae41c212dc 100644
--- a/include/linux/nvme-fc-driver.h
+++ b/include/linux/nvme-fc-driver.h
@@ -282,6 +282,8 @@ struct nvme_fc_remote_port {
  *
  * Host/Initiator Transport Entrypoints/Parameters:
  *
+ * @module:  The LLDD module using the interface
+ *
  * @localport_delete:  The LLDD initiates deletion of a localport via
  *       nvme_fc_deregister_localport(). However, the teardown is
  *       asynchronous. This routine is called upon the completion of the
@@ -395,6 +397,8 @@ struct nvme_fc_remote_port {
  *       Value is Mandatory. Allowed to be zero.
  */
 struct nvme_fc_port_template {
+	struct module	*module;
+
 	/* initiator-based functions */
 	void	(*localport_delete)(struct nvme_fc_local_port *);
 	void	(*remoteport_delete)(struct nvme_fc_remote_port *);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2019-12-20 14:37 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-20 14:34 [PATCH AUTOSEL 4.19 01/34] nvme_fc: add module to ops template to allow module references Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 02/34] nvme-fc: fix double-free scenarios on hw queues Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 03/34] drm/amdgpu: add check before enabling/disabling broadcast mode Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 04/34] drm/amdgpu: add cache flush workaround to gfx8 emit_fence Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 05/34] drm/amd/display: Fixed kernel panic when booting with DP-to-HDMI dongle Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 06/34] iio: adc: max9611: Fix too short conversion time delay Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 07/34] PM / devfreq: Fix devfreq_notifier_call returning errno Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 08/34] PM / devfreq: Set scaling_max_freq to max on OPP notifier error Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 09/34] PM / devfreq: Don't fail devfreq_dev_release if not in list Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 10/34] afs: Fix afs_find_server lookups for ipv4 peers Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 11/34] afs: Fix SELinux setting security label on /afs Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 12/34] RDMA/cma: add missed unregister_pernet_subsys in init failure Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 13/34] rxe: correctly calculate iCRC for unaligned payloads Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 14/34] scsi: lpfc: Fix memory leak on lpfc_bsg_write_ebuf_set func Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 15/34] scsi: qla2xxx: Drop superfluous INIT_WORK of del_work Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 16/34] scsi: qla2xxx: Don't call qlt_async_event twice Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 17/34] scsi: qla2xxx: Fix PLOGI payload and ELS IOCB dump length Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 18/34] scsi: qla2xxx: Configure local loop for N2N target Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 19/34] scsi: qla2xxx: Send Notify ACK after N2N PLOGI Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 20/34] scsi: qla2xxx: Ignore PORT UPDATE " Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 21/34] scsi: iscsi: qla4xxx: fix double free in probe Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 22/34] scsi: libsas: stop discovering if oob mode is disconnected Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 23/34] drm/nouveau: Move the declaration of struct nouveau_conn_atom up a bit Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 24/34] usb: gadget: fix wrong endpoint desc Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 25/34] net: make socket read/write_iter() honor IOCB_NOWAIT Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 26/34] afs: Fix creation calls in the dynamic root to fail with EOPNOTSUPP Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 27/34] md: raid1: check rdev before reference in raid1_sync_request func Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 28/34] s390/cpum_sf: Adjust sampling interval to avoid hitting sample limits Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 29/34] s390/cpum_sf: Avoid SBD overflow condition in irq handler Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 30/34] IB/mlx4: Follow mirror sequence of device add during device removal Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 31/34] IB/mlx5: Fix steering rule of drop and count Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 32/34] xen-blkback: prevent premature module unload Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 33/34] xen/balloon: fix ballooned page accounting without hotplug enabled Sasha Levin
2019-12-20 14:34 ` [PATCH AUTOSEL 4.19 34/34] PM / hibernate: memory_bm_find_bit(): Tighten node optimisation Sasha Levin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).