linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] SCSI ALUA device handler bug fixes
@ 2017-03-18  0:02 Bart Van Assche
  2017-03-18  0:02 ` [PATCH 1/3] scsi_dh_alua: Check scsi_device_get() return value Bart Van Assche
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Bart Van Assche @ 2017-03-18  0:02 UTC (permalink / raw)
  To: Martin K . Petersen; +Cc: linux-scsi, Hannes Reinecke, Bart Van Assche

Hello Martin,

These three patches are what I came up with while I was chasing a
scsi_device_put() crash. Please consider these for inclusion in the
upstream kernel.

Thanks,

Bart.

Bart Van Assche (3):
  scsi_dh_alua: Check scsi_device_get() return value
  scsi_dh_alua: Ensure that alua_activate() calls the completion
    function
  scsi_dh_alua: Warn if the first argument of alua_rtpg_queue() is NULL

 drivers/scsi/device_handler/scsi_dh_alua.c | 38 +++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 14 deletions(-)

-- 
2.12.0

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

* [PATCH 1/3] scsi_dh_alua: Check scsi_device_get() return value
  2017-03-18  0:02 [PATCH 0/3] SCSI ALUA device handler bug fixes Bart Van Assche
@ 2017-03-18  0:02 ` Bart Van Assche
  2017-03-18 11:17   ` Hannes Reinecke
  2017-03-18  0:02 ` [PATCH 2/3] scsi_dh_alua: Ensure that alua_activate() calls the completion function Bart Van Assche
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Bart Van Assche @ 2017-03-18  0:02 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Hannes Reinecke, Bart Van Assche, Tang Junhui, stable

Do not queue ALUA work nor call scsi_device_put() if the scsi_device_get()
call fails. This patch fixes the following crash:

general protection fault: 0000 [#1] SMP
RIP: 0010:scsi_device_put+0xb/0x30
Call Trace:
 scsi_disk_put+0x2d/0x40
 sd_release+0x3d/0xb0
 __blkdev_put+0x29e/0x360
 blkdev_put+0x49/0x170
 dm_put_table_device+0x58/0xc0 [dm_mod]
 dm_put_device+0x70/0xc0 [dm_mod]
 free_priority_group+0x92/0xc0 [dm_multipath]
 free_multipath+0x70/0xc0 [dm_multipath]
 multipath_dtr+0x19/0x20 [dm_multipath]
 dm_table_destroy+0x67/0x120 [dm_mod]
 dev_suspend+0xde/0x240 [dm_mod]
 ctl_ioctl+0x1f5/0x520 [dm_mod]
 dm_ctl_ioctl+0xe/0x20 [dm_mod]
 do_vfs_ioctl+0x8f/0x700
 SyS_ioctl+0x3c/0x70
 entry_SYSCALL_64_fastpath+0x18/0xad

Fixes: commit 03197b61c5ec ("scsi_dh_alua: Use workqueue for RTPG")
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Tang Junhui <tang.junhui@zte.com.cn>
Cc: <stable@vger.kernel.org>
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 48e200102221..e0b15f3dd303 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -870,7 +870,7 @@ static void alua_rtpg_queue(struct alua_port_group *pg,
 	unsigned long flags;
 	struct workqueue_struct *alua_wq = kaluad_wq;
 
-	if (!pg)
+	if (!pg || scsi_device_get(sdev))
 		return;
 
 	spin_lock_irqsave(&pg->lock, flags);
@@ -884,14 +884,12 @@ static void alua_rtpg_queue(struct alua_port_group *pg,
 		pg->flags |= ALUA_PG_RUN_RTPG;
 		kref_get(&pg->kref);
 		pg->rtpg_sdev = sdev;
-		scsi_device_get(sdev);
 		start_queue = 1;
 	} else if (!(pg->flags & ALUA_PG_RUN_RTPG) && force) {
 		pg->flags |= ALUA_PG_RUN_RTPG;
 		/* Do not queue if the worker is already running */
 		if (!(pg->flags & ALUA_PG_RUNNING)) {
 			kref_get(&pg->kref);
-			sdev = NULL;
 			start_queue = 1;
 		}
 	}
@@ -900,13 +898,15 @@ static void alua_rtpg_queue(struct alua_port_group *pg,
 		alua_wq = kaluad_sync_wq;
 	spin_unlock_irqrestore(&pg->lock, flags);
 
-	if (start_queue &&
-	    !queue_delayed_work(alua_wq, &pg->rtpg_work,
-				msecs_to_jiffies(ALUA_RTPG_DELAY_MSECS))) {
-		if (sdev)
-			scsi_device_put(sdev);
-		kref_put(&pg->kref, release_port_group);
+	if (start_queue) {
+		if (queue_delayed_work(alua_wq, &pg->rtpg_work,
+				msecs_to_jiffies(ALUA_RTPG_DELAY_MSECS)))
+			sdev = NULL;
+		else
+			kref_put(&pg->kref, release_port_group);
 	}
+	if (sdev)
+		scsi_device_put(sdev);
 }
 
 /*
-- 
2.12.0

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

* [PATCH 2/3] scsi_dh_alua: Ensure that alua_activate() calls the completion function
  2017-03-18  0:02 [PATCH 0/3] SCSI ALUA device handler bug fixes Bart Van Assche
  2017-03-18  0:02 ` [PATCH 1/3] scsi_dh_alua: Check scsi_device_get() return value Bart Van Assche
@ 2017-03-18  0:02 ` Bart Van Assche
  2017-03-18 11:19   ` Hannes Reinecke
  2017-03-18  0:02 ` [PATCH 3/3] scsi_dh_alua: Warn if the first argument of alua_rtpg_queue() is NULL Bart Van Assche
  2017-03-19 17:17 ` [PATCH 0/3] SCSI ALUA device handler bug fixes Martin K. Petersen
  3 siblings, 1 reply; 8+ messages in thread
From: Bart Van Assche @ 2017-03-18  0:02 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Hannes Reinecke, Bart Van Assche, Tang Junhui, stable

Callers of scsi_dh_activate(), e.g. dm-mpath, assume that this
function either returns an error code or calls the completion
function. Make alua_activate() call the completion function even
if scsi_device_get() fails.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Tang Junhui <tang.junhui@zte.com.cn>
Cc: <stable@vger.kernel.org>
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index e0b15f3dd303..b6849d3ecefe 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -113,7 +113,7 @@ struct alua_queue_data {
 #define ALUA_POLICY_SWITCH_ALL		1
 
 static void alua_rtpg_work(struct work_struct *work);
-static void alua_rtpg_queue(struct alua_port_group *pg,
+static bool alua_rtpg_queue(struct alua_port_group *pg,
 			    struct scsi_device *sdev,
 			    struct alua_queue_data *qdata, bool force);
 static void alua_check(struct scsi_device *sdev, bool force);
@@ -862,7 +862,13 @@ static void alua_rtpg_work(struct work_struct *work)
 	kref_put(&pg->kref, release_port_group);
 }
 
-static void alua_rtpg_queue(struct alua_port_group *pg,
+/**
+ * alua_rtpg_queue() - cause RTPG to be submitted asynchronously
+ *
+ * Returns true if and only if alua_rtpg_work() will be called asynchronously.
+ * That function is responsible for calling @qdata->fn().
+ */
+static bool alua_rtpg_queue(struct alua_port_group *pg,
 			    struct scsi_device *sdev,
 			    struct alua_queue_data *qdata, bool force)
 {
@@ -871,7 +877,7 @@ static void alua_rtpg_queue(struct alua_port_group *pg,
 	struct workqueue_struct *alua_wq = kaluad_wq;
 
 	if (!pg || scsi_device_get(sdev))
-		return;
+		return false;
 
 	spin_lock_irqsave(&pg->lock, flags);
 	if (qdata) {
@@ -907,6 +913,8 @@ static void alua_rtpg_queue(struct alua_port_group *pg,
 	}
 	if (sdev)
 		scsi_device_put(sdev);
+
+	return true;
 }
 
 /*
@@ -1007,11 +1015,13 @@ static int alua_activate(struct scsi_device *sdev,
 		mutex_unlock(&h->init_mutex);
 		goto out;
 	}
-	fn = NULL;
 	rcu_read_unlock();
 	mutex_unlock(&h->init_mutex);
 
-	alua_rtpg_queue(pg, sdev, qdata, true);
+	if (alua_rtpg_queue(pg, sdev, qdata, true))
+		fn = NULL;
+	else
+		err = SCSI_DH_DEV_OFFLINED;
 	kref_put(&pg->kref, release_port_group);
 out:
 	if (fn)
-- 
2.12.0

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

* [PATCH 3/3] scsi_dh_alua: Warn if the first argument of alua_rtpg_queue() is NULL
  2017-03-18  0:02 [PATCH 0/3] SCSI ALUA device handler bug fixes Bart Van Assche
  2017-03-18  0:02 ` [PATCH 1/3] scsi_dh_alua: Check scsi_device_get() return value Bart Van Assche
  2017-03-18  0:02 ` [PATCH 2/3] scsi_dh_alua: Ensure that alua_activate() calls the completion function Bart Van Assche
@ 2017-03-18  0:02 ` Bart Van Assche
  2017-03-18 11:19   ` Hannes Reinecke
  2017-03-19 17:17 ` [PATCH 0/3] SCSI ALUA device handler bug fixes Martin K. Petersen
  3 siblings, 1 reply; 8+ messages in thread
From: Bart Van Assche @ 2017-03-18  0:02 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, Hannes Reinecke, Bart Van Assche, Tang Junhui

Callers must provide a valid port group to alua_rtpg_queue().
Issue a kernel warning if that is not the case.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Tang Junhui <tang.junhui@zte.com.cn>
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index b6849d3ecefe..c01b47e5b55a 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -876,7 +876,7 @@ static bool alua_rtpg_queue(struct alua_port_group *pg,
 	unsigned long flags;
 	struct workqueue_struct *alua_wq = kaluad_wq;
 
-	if (!pg || scsi_device_get(sdev))
+	if (WARN_ON_ONCE(!pg) || scsi_device_get(sdev))
 		return false;
 
 	spin_lock_irqsave(&pg->lock, flags);
-- 
2.12.0

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

* Re: [PATCH 1/3] scsi_dh_alua: Check scsi_device_get() return value
  2017-03-18  0:02 ` [PATCH 1/3] scsi_dh_alua: Check scsi_device_get() return value Bart Van Assche
@ 2017-03-18 11:17   ` Hannes Reinecke
  0 siblings, 0 replies; 8+ messages in thread
From: Hannes Reinecke @ 2017-03-18 11:17 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen; +Cc: linux-scsi, Tang Junhui, stable

On 03/18/2017 01:02 AM, Bart Van Assche wrote:
> Do not queue ALUA work nor call scsi_device_put() if the scsi_device_get()
> call fails. This patch fixes the following crash:
> 
> general protection fault: 0000 [#1] SMP
> RIP: 0010:scsi_device_put+0xb/0x30
> Call Trace:
>  scsi_disk_put+0x2d/0x40
>  sd_release+0x3d/0xb0
>  __blkdev_put+0x29e/0x360
>  blkdev_put+0x49/0x170
>  dm_put_table_device+0x58/0xc0 [dm_mod]
>  dm_put_device+0x70/0xc0 [dm_mod]
>  free_priority_group+0x92/0xc0 [dm_multipath]
>  free_multipath+0x70/0xc0 [dm_multipath]
>  multipath_dtr+0x19/0x20 [dm_multipath]
>  dm_table_destroy+0x67/0x120 [dm_mod]
>  dev_suspend+0xde/0x240 [dm_mod]
>  ctl_ioctl+0x1f5/0x520 [dm_mod]
>  dm_ctl_ioctl+0xe/0x20 [dm_mod]
>  do_vfs_ioctl+0x8f/0x700
>  SyS_ioctl+0x3c/0x70
>  entry_SYSCALL_64_fastpath+0x18/0xad
> 
> Fixes: commit 03197b61c5ec ("scsi_dh_alua: Use workqueue for RTPG")
> Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
> Cc: Hannes Reinecke <hare@suse.de>
> Cc: Tang Junhui <tang.junhui@zte.com.cn>
> Cc: <stable@vger.kernel.org>
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		      zSeries & Storage
hare@suse.de			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)

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

* Re: [PATCH 2/3] scsi_dh_alua: Ensure that alua_activate() calls the completion function
  2017-03-18  0:02 ` [PATCH 2/3] scsi_dh_alua: Ensure that alua_activate() calls the completion function Bart Van Assche
@ 2017-03-18 11:19   ` Hannes Reinecke
  0 siblings, 0 replies; 8+ messages in thread
From: Hannes Reinecke @ 2017-03-18 11:19 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen; +Cc: linux-scsi, Tang Junhui, stable

On 03/18/2017 01:02 AM, Bart Van Assche wrote:
> Callers of scsi_dh_activate(), e.g. dm-mpath, assume that this
> function either returns an error code or calls the completion
> function. Make alua_activate() call the completion function even
> if scsi_device_get() fails.
> 
> Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
> Cc: Hannes Reinecke <hare@suse.de>
> Cc: Tang Junhui <tang.junhui@zte.com.cn>
> Cc: <stable@vger.kernel.org>
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 20 +++++++++++++++-----
>  1 file changed, 15 insertions(+), 5 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		      zSeries & Storage
hare@suse.de			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)

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

* Re: [PATCH 3/3] scsi_dh_alua: Warn if the first argument of alua_rtpg_queue() is NULL
  2017-03-18  0:02 ` [PATCH 3/3] scsi_dh_alua: Warn if the first argument of alua_rtpg_queue() is NULL Bart Van Assche
@ 2017-03-18 11:19   ` Hannes Reinecke
  0 siblings, 0 replies; 8+ messages in thread
From: Hannes Reinecke @ 2017-03-18 11:19 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen; +Cc: linux-scsi, Tang Junhui

On 03/18/2017 01:02 AM, Bart Van Assche wrote:
> Callers must provide a valid port group to alua_rtpg_queue().
> Issue a kernel warning if that is not the case.
> 
> Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
> Cc: Hannes Reinecke <hare@suse.de>
> Cc: Tang Junhui <tang.junhui@zte.com.cn>
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
> index b6849d3ecefe..c01b47e5b55a 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -876,7 +876,7 @@ static bool alua_rtpg_queue(struct alua_port_group *pg,
>  	unsigned long flags;
>  	struct workqueue_struct *alua_wq = kaluad_wq;
>  
> -	if (!pg || scsi_device_get(sdev))
> +	if (WARN_ON_ONCE(!pg) || scsi_device_get(sdev))
>  		return false;
>  
>  	spin_lock_irqsave(&pg->lock, flags);
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		      zSeries & Storage
hare@suse.de			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)

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

* Re: [PATCH 0/3] SCSI ALUA device handler bug fixes
  2017-03-18  0:02 [PATCH 0/3] SCSI ALUA device handler bug fixes Bart Van Assche
                   ` (2 preceding siblings ...)
  2017-03-18  0:02 ` [PATCH 3/3] scsi_dh_alua: Warn if the first argument of alua_rtpg_queue() is NULL Bart Van Assche
@ 2017-03-19 17:17 ` Martin K. Petersen
  3 siblings, 0 replies; 8+ messages in thread
From: Martin K. Petersen @ 2017-03-19 17:17 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: Martin K . Petersen, linux-scsi, Hannes Reinecke

Bart Van Assche <bart.vanassche@sandisk.com> writes:

Bart,

> These three patches are what I came up with while I was chasing a
> scsi_device_put() crash. Please consider these for inclusion in the
> upstream kernel.

Applied to 4.11/scsi-fixes.

-- 
Martin K. Petersen	Oracle Linux Engineering

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

end of thread, other threads:[~2017-03-19 17:18 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-03-18  0:02 [PATCH 0/3] SCSI ALUA device handler bug fixes Bart Van Assche
2017-03-18  0:02 ` [PATCH 1/3] scsi_dh_alua: Check scsi_device_get() return value Bart Van Assche
2017-03-18 11:17   ` Hannes Reinecke
2017-03-18  0:02 ` [PATCH 2/3] scsi_dh_alua: Ensure that alua_activate() calls the completion function Bart Van Assche
2017-03-18 11:19   ` Hannes Reinecke
2017-03-18  0:02 ` [PATCH 3/3] scsi_dh_alua: Warn if the first argument of alua_rtpg_queue() is NULL Bart Van Assche
2017-03-18 11:19   ` Hannes Reinecke
2017-03-19 17:17 ` [PATCH 0/3] SCSI ALUA device handler bug fixes Martin K. Petersen

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).