* [PATCH v2] Avoid that ATA error handling can trigger a kernel hang or oops
@ 2018-02-22 19:30 Bart Van Assche
2018-02-23 15:46 ` Natanael Copa
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Bart Van Assche @ 2018-02-22 19:30 UTC (permalink / raw)
To: Martin K . Petersen, James E . J . Bottomley
Cc: linux-scsi, Bart Van Assche, Natanael Copa, Damien Le Moal,
Alexandre Oliva, Pavel Tikhomirov, Hannes Reinecke,
Johannes Thumshirn, stable
Avoid that the recently introduced call_rcu() call in the SCSI core
triggers a double call_rcu() call.
Reported-by: Natanael Copa <ncopa@alpinelinux.org>
Reported-by: Damien Le Moal <damien.lemoal@wdc.com>
References: https://bugzilla.kernel.org/show_bug.cgi?id=198861
Fixes: 3bd6f43f5cb3 ("scsi: core: Ensure that the SCSI error handler gets woken up")
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
Cc: Natanael Copa <ncopa@alpinelinux.org>
Cc: Damien Le Moal <damien.lemoal@wdc.com>
Cc: Alexandre Oliva <oliva@gnu.org>
Cc: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Johannes Thumshirn <jthumshirn@suse.de>
Cc: <stable@vger.kernel.org>
---
drivers/scsi/hosts.c | 3 ---
drivers/scsi/scsi_error.c | 5 +++--
drivers/scsi/scsi_lib.c | 2 ++
include/scsi/scsi_cmnd.h | 3 +++
include/scsi/scsi_host.h | 2 --
5 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index a0a7e4ff255c..7279d3d2e941 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -334,8 +334,6 @@ static void scsi_host_dev_release(struct device *dev)
if (shost->work_q)
destroy_workqueue(shost->work_q);
- destroy_rcu_head(&shost->rcu);
-
if (shost->shost_state == SHOST_CREATED) {
/*
* Free the shost_dev device name here if scsi_host_alloc()
@@ -404,7 +402,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
INIT_LIST_HEAD(&shost->starved_list);
init_waitqueue_head(&shost->host_wait);
mutex_init(&shost->scan_mutex);
- init_rcu_head(&shost->rcu);
index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL);
if (index < 0)
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 96f988a7efda..9b0242f84407 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -229,7 +229,8 @@ static void scsi_eh_reset(struct scsi_cmnd *scmd)
static void scsi_eh_inc_host_failed(struct rcu_head *head)
{
- struct Scsi_Host *shost = container_of(head, typeof(*shost), rcu);
+ struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu);
+ struct Scsi_Host *shost = scmd->device->host;
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
@@ -265,7 +266,7 @@ void scsi_eh_scmd_add(struct scsi_cmnd *scmd)
* Ensure that all tasks observe the host state change before the
* host_failed change.
*/
- call_rcu(&shost->rcu, scsi_eh_inc_host_failed);
+ call_rcu(&scmd->rcu, scsi_eh_inc_host_failed);
}
/**
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index aea5a1ae318b..e1ca2160aa40 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -671,6 +671,7 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
if (!blk_rq_is_scsi(req)) {
WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED));
cmd->flags &= ~SCMD_INITIALIZED;
+ destroy_rcu_head(&cmd->rcu);
}
if (req->mq_ctx) {
@@ -1151,6 +1152,7 @@ static void scsi_initialize_rq(struct request *rq)
struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
scsi_req_init(&cmd->req);
+ init_rcu_head(&cmd->rcu);
cmd->jiffies_at_alloc = jiffies;
cmd->retries = 0;
}
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index d8d4a902a88d..2280b2351739 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -68,6 +68,9 @@ struct scsi_cmnd {
struct list_head list; /* scsi_cmnd participates in queue lists */
struct list_head eh_entry; /* entry for the host eh_cmd_q */
struct delayed_work abort_work;
+
+ struct rcu_head rcu;
+
int eh_eflags; /* Used by error handlr */
/*
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 19317585ae48..7aedb6776b4f 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -577,8 +577,6 @@ struct Scsi_Host {
struct blk_mq_tag_set tag_set;
};
- struct rcu_head rcu;
-
atomic_t host_busy; /* commands actually active on low-level */
atomic_t host_blocked;
--
2.16.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2] Avoid that ATA error handling can trigger a kernel hang or oops
2018-02-22 19:30 [PATCH v2] Avoid that ATA error handling can trigger a kernel hang or oops Bart Van Assche
@ 2018-02-23 15:46 ` Natanael Copa
2018-02-26 11:52 ` Salvatore Bonaccorso
2018-02-27 18:53 ` Bart Van Assche
2018-02-28 2:14 ` Martin K. Petersen
2 siblings, 1 reply; 6+ messages in thread
From: Natanael Copa @ 2018-02-23 15:46 UTC (permalink / raw)
To: Bart Van Assche
Cc: Martin K . Petersen, James E . J . Bottomley, linux-scsi,
Damien Le Moal, Alexandre Oliva, Pavel Tikhomirov,
Hannes Reinecke, Johannes Thumshirn, stable
On Thu, 22 Feb 2018 11:30:20 -0800
Bart Van Assche <bart.vanassche@wdc.com> wrote:
> Avoid that the recently introduced call_rcu() call in the SCSI core
> triggers a double call_rcu() call.
This patch also prevents my machine from hanging. However, the ATA
error messages that I previously have had are gone, so I don't know if
it is because the underlying problem is gone, or if the error messages
are simply not reported.
-nc
>
> Reported-by: Natanael Copa <ncopa@alpinelinux.org>
> Reported-by: Damien Le Moal <damien.lemoal@wdc.com>
> References: https://bugzilla.kernel.org/show_bug.cgi?id=198861
> Fixes: 3bd6f43f5cb3 ("scsi: core: Ensure that the SCSI error handler gets woken up")
> Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
> Cc: Natanael Copa <ncopa@alpinelinux.org>
> Cc: Damien Le Moal <damien.lemoal@wdc.com>
> Cc: Alexandre Oliva <oliva@gnu.org>
> Cc: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
> Cc: Hannes Reinecke <hare@suse.com>
> Cc: Johannes Thumshirn <jthumshirn@suse.de>
> Cc: <stable@vger.kernel.org>
> ---
> drivers/scsi/hosts.c | 3 ---
> drivers/scsi/scsi_error.c | 5 +++--
> drivers/scsi/scsi_lib.c | 2 ++
> include/scsi/scsi_cmnd.h | 3 +++
> include/scsi/scsi_host.h | 2 --
> 5 files changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
> index a0a7e4ff255c..7279d3d2e941 100644
> --- a/drivers/scsi/hosts.c
> +++ b/drivers/scsi/hosts.c
> @@ -334,8 +334,6 @@ static void scsi_host_dev_release(struct device *dev)
> if (shost->work_q)
> destroy_workqueue(shost->work_q);
>
> - destroy_rcu_head(&shost->rcu);
> -
> if (shost->shost_state == SHOST_CREATED) {
> /*
> * Free the shost_dev device name here if scsi_host_alloc()
> @@ -404,7 +402,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
> INIT_LIST_HEAD(&shost->starved_list);
> init_waitqueue_head(&shost->host_wait);
> mutex_init(&shost->scan_mutex);
> - init_rcu_head(&shost->rcu);
>
> index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL);
> if (index < 0)
> diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
> index 96f988a7efda..9b0242f84407 100644
> --- a/drivers/scsi/scsi_error.c
> +++ b/drivers/scsi/scsi_error.c
> @@ -229,7 +229,8 @@ static void scsi_eh_reset(struct scsi_cmnd *scmd)
>
> static void scsi_eh_inc_host_failed(struct rcu_head *head)
> {
> - struct Scsi_Host *shost = container_of(head, typeof(*shost), rcu);
> + struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu);
> + struct Scsi_Host *shost = scmd->device->host;
> unsigned long flags;
>
> spin_lock_irqsave(shost->host_lock, flags);
> @@ -265,7 +266,7 @@ void scsi_eh_scmd_add(struct scsi_cmnd *scmd)
> * Ensure that all tasks observe the host state change before the
> * host_failed change.
> */
> - call_rcu(&shost->rcu, scsi_eh_inc_host_failed);
> + call_rcu(&scmd->rcu, scsi_eh_inc_host_failed);
> }
>
> /**
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index aea5a1ae318b..e1ca2160aa40 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -671,6 +671,7 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
> if (!blk_rq_is_scsi(req)) {
> WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED));
> cmd->flags &= ~SCMD_INITIALIZED;
> + destroy_rcu_head(&cmd->rcu);
> }
>
> if (req->mq_ctx) {
> @@ -1151,6 +1152,7 @@ static void scsi_initialize_rq(struct request *rq)
> struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
>
> scsi_req_init(&cmd->req);
> + init_rcu_head(&cmd->rcu);
> cmd->jiffies_at_alloc = jiffies;
> cmd->retries = 0;
> }
> diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
> index d8d4a902a88d..2280b2351739 100644
> --- a/include/scsi/scsi_cmnd.h
> +++ b/include/scsi/scsi_cmnd.h
> @@ -68,6 +68,9 @@ struct scsi_cmnd {
> struct list_head list; /* scsi_cmnd participates in queue lists */
> struct list_head eh_entry; /* entry for the host eh_cmd_q */
> struct delayed_work abort_work;
> +
> + struct rcu_head rcu;
> +
> int eh_eflags; /* Used by error handlr */
>
> /*
> diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
> index 19317585ae48..7aedb6776b4f 100644
> --- a/include/scsi/scsi_host.h
> +++ b/include/scsi/scsi_host.h
> @@ -577,8 +577,6 @@ struct Scsi_Host {
> struct blk_mq_tag_set tag_set;
> };
>
> - struct rcu_head rcu;
> -
> atomic_t host_busy; /* commands actually active on low-level */
> atomic_t host_blocked;
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] Avoid that ATA error handling can trigger a kernel hang or oops
2018-02-23 15:46 ` Natanael Copa
@ 2018-02-26 11:52 ` Salvatore Bonaccorso
0 siblings, 0 replies; 6+ messages in thread
From: Salvatore Bonaccorso @ 2018-02-26 11:52 UTC (permalink / raw)
To: Natanael Copa
Cc: Bart Van Assche, Martin K . Petersen, James E . J . Bottomley,
linux-scsi, Damien Le Moal, Alexandre Oliva, Pavel Tikhomirov,
Hannes Reinecke, Johannes Thumshirn, stable, Jean-Francois Pirus
Hi,
On Fri, Feb 23, 2018 at 04:46:30PM +0100, Natanael Copa wrote:
> On Thu, 22 Feb 2018 11:30:20 -0800
> Bart Van Assche <bart.vanassche@wdc.com> wrote:
>
> > Avoid that the recently introduced call_rcu() call in the SCSI core
> > triggers a double call_rcu() call.
>
> This patch also prevents my machine from hanging. However, the ATA
> error messages that I previously have had are gone, so I don't know if
> it is because the underlying problem is gone, or if the error messages
> are simply not reported.
For reference, the patch has as well been confirmed to solve the
problem for Jean-Francois Pirus in https://bugs.debian.org/891467
(on top of 4.15.4)
Regards,
Salvatore
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] Avoid that ATA error handling can trigger a kernel hang or oops
2018-02-22 19:30 [PATCH v2] Avoid that ATA error handling can trigger a kernel hang or oops Bart Van Assche
2018-02-23 15:46 ` Natanael Copa
@ 2018-02-27 18:53 ` Bart Van Assche
2018-02-27 21:11 ` Damien Le Moal
2018-02-28 2:14 ` Martin K. Petersen
2 siblings, 1 reply; 6+ messages in thread
From: Bart Van Assche @ 2018-02-27 18:53 UTC (permalink / raw)
To: jejb@linux.vnet.ibm.com, martin.petersen@oracle.com
Cc: jthumshirn@suse.de, Damien Le Moal, stable@vger.kernel.org,
oliva@gnu.org, linux-scsi@vger.kernel.org, hare@suse.com,
ptikhomirov@virtuozzo.com, ncopa@alpinelinux.org
On Thu, 2018-02-22 at 11:30 -0800, Bart Van Assche wrote:
> Avoid that the recently introduced call_rcu() call in the SCSI core
> triggers a double call_rcu() call.
> [ ... ]
Can anyone review this patch? Multiple users have confirmed independently
that this patch fixes the double call_rcu() issue for them.
Thanks,
Bart.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] Avoid that ATA error handling can trigger a kernel hang or oops
2018-02-27 18:53 ` Bart Van Assche
@ 2018-02-27 21:11 ` Damien Le Moal
0 siblings, 0 replies; 6+ messages in thread
From: Damien Le Moal @ 2018-02-27 21:11 UTC (permalink / raw)
To: Bart Van Assche, jejb@linux.vnet.ibm.com,
martin.petersen@oracle.com
Cc: jthumshirn@suse.de, stable@vger.kernel.org, oliva@gnu.org,
linux-scsi@vger.kernel.org, hare@suse.com,
ptikhomirov@virtuozzo.com, ncopa@alpinelinux.org
On 2018/02/27 10:53, Bart Van Assche wrote:
> On Thu, 2018-02-22 at 11:30 -0800, Bart Van Assche wrote:
>> Avoid that the recently introduced call_rcu() call in the SCSI core
>> triggers a double call_rcu() call.
>> [ ... ]
>
> Can anyone review this patch? Multiple users have confirmed independently
> that this patch fixes the double call_rcu() issue for them.
>
> Thanks,
>
> Bart.
Please feel free to add:
Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com>
Tested-by: Damien Le Moal <damien.lemoal@wdc.com>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] Avoid that ATA error handling can trigger a kernel hang or oops
2018-02-22 19:30 [PATCH v2] Avoid that ATA error handling can trigger a kernel hang or oops Bart Van Assche
2018-02-23 15:46 ` Natanael Copa
2018-02-27 18:53 ` Bart Van Assche
@ 2018-02-28 2:14 ` Martin K. Petersen
2 siblings, 0 replies; 6+ messages in thread
From: Martin K. Petersen @ 2018-02-28 2:14 UTC (permalink / raw)
To: Bart Van Assche
Cc: Martin K . Petersen, James E . J . Bottomley, linux-scsi,
Natanael Copa, Damien Le Moal, Alexandre Oliva, Pavel Tikhomirov,
Hannes Reinecke, Johannes Thumshirn, stable
Bart,
> Avoid that the recently introduced call_rcu() call in the SCSI core
> triggers a double call_rcu() call.
Applied to 4.16/scsi-fixes. Thank you!
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-02-28 2:14 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-22 19:30 [PATCH v2] Avoid that ATA error handling can trigger a kernel hang or oops Bart Van Assche
2018-02-23 15:46 ` Natanael Copa
2018-02-26 11:52 ` Salvatore Bonaccorso
2018-02-27 18:53 ` Bart Van Assche
2018-02-27 21:11 ` Damien Le Moal
2018-02-28 2:14 ` Martin K. Petersen
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.