scsi: core: Avoid that ATA error handling can trigger a kernel hang or oops
Closes: #891467
This commit is contained in:
parent
90b8cc7a38
commit
8039021914
|
@ -413,6 +413,10 @@ linux (4.15.9-1) UNRELEASED; urgency=medium
|
|||
* [arm64] Apply patch from linux-next to fix eMMC corruption on
|
||||
Odroid-C2 (Closes: #879072).
|
||||
|
||||
[ Salvatore Bonaccorso ]
|
||||
* scsi: core: Avoid that ATA error handling can trigger a kernel hang or
|
||||
oops (Closes: #891467)
|
||||
|
||||
-- Salvatore Bonaccorso <carnil@debian.org> Tue, 20 Feb 2018 21:51:39 +0100
|
||||
|
||||
linux (4.15.4-1) unstable; urgency=medium
|
||||
|
|
128
debian/patches/bugfix/all/scsi-core-Avoid-that-ATA-error-handling-can-trigger-.patch
vendored
Normal file
128
debian/patches/bugfix/all/scsi-core-Avoid-that-ATA-error-handling-can-trigger-.patch
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
From: Bart Van Assche <bart.vanassche@wdc.com>
|
||||
Date: Thu, 22 Feb 2018 11:30:20 -0800
|
||||
Subject: scsi: core: Avoid that ATA error handling can trigger a kernel hang
|
||||
or oops
|
||||
Origin: https://git.kernel.org/linus/3be8828fc507cdafe7040a3dcf361a2bcd8e305b
|
||||
Bug: https://bugzilla.kernel.org/show_bug.cgi?id=198861
|
||||
Bug-Debian: https://bugs.debian.org/891467
|
||||
|
||||
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>
|
||||
Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com>
|
||||
Tested-by: Damien Le Moal <damien.lemoal@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>
|
||||
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
|
||||
---
|
||||
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 57bf43e34863..dd9464920456 100644
|
||||
--- a/drivers/scsi/hosts.c
|
||||
+++ b/drivers/scsi/hosts.c
|
||||
@@ -328,8 +328,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 d042915ce895..ca53a5f785ee 100644
|
||||
--- a/drivers/scsi/scsi_error.c
|
||||
+++ b/drivers/scsi/scsi_error.c
|
||||
@@ -223,7 +223,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);
|
||||
@@ -259,7 +260,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 5cbc69b2b1ae..4af1682f5ff5 100644
|
||||
--- a/drivers/scsi/scsi_lib.c
|
||||
+++ b/drivers/scsi/scsi_lib.c
|
||||
@@ -670,6 +670,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) {
|
||||
@@ -1150,6 +1151,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 949a016dd7fa..0382ceab2eba 100644
|
||||
--- a/include/scsi/scsi_cmnd.h
|
||||
+++ b/include/scsi/scsi_cmnd.h
|
||||
@@ -69,6 +69,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 1a1df0d21ee3..a8b7bf879ced 100644
|
||||
--- a/include/scsi/scsi_host.h
|
||||
+++ b/include/scsi/scsi_host.h
|
||||
@@ -571,8 +571,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.11.0
|
||||
|
|
@ -80,6 +80,7 @@ bugfix/all/partially-revert-usb-kconfig-using-select-for-usb_co.patch
|
|||
bugfix/all/kbuild-include-addtree-remove-quotes-before-matching-path.patch
|
||||
debian/revert-objtool-fix-config_stack_validation-y-warning.patch
|
||||
bugfix/all/crypto-ecc-fix-null-pointer-deref.-on-no-default_rng.patch
|
||||
bugfix/all/scsi-core-Avoid-that-ATA-error-handling-can-trigger-.patch
|
||||
|
||||
# Miscellaneous features
|
||||
|
||||
|
|
Loading…
Reference in New Issue