Skip to contentSkip to conversation

Patch "scsi: core: Avoid that ATA error handling can trigger a kernel hang or oops" has been added to the 4.14-stable tree

PATCH [email protected] 1 participant 1 message Mar 12, 2018

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

scsi: core: Avoid that ATA error handling can trigger a kernel hang or oops

to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
scsi-core-avoid-that-ata-error-handling-can-trigger-a-kernel-hang-or-oops.patch
and it can be found in the queue-4.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 3be8828fc507cdafe7040a3dcf361a2bcd8e305b Mon Sep 17 00:00:00 2001

From: Bart Van Assche <[email protected]>
Date: Thu, 22 Feb 2018 11:30:20 -0800
Subject: scsi: core: Avoid that ATA error handling can trigger a kernel hang or oops

From: Bart Van Assche <[email protected]>

commit 3be8828fc507cdafe7040a3dcf361a2bcd8e305b upstream.

Avoid that the recently introduced call_rcu() call in the SCSI core triggers a double call_rcu() call.

References: https://bugzilla.kernel.org/show_bug.cgi?id=198861

Fixes 3bd6f43f5cb3 ("scsi: core: Ensure that the SCSI error handler gets woken up")
Cc Natanael Copa <[email protected]>
Cc Damien Le Moal <[email protected]>
Cc Alexandre Oliva <[email protected]>
Cc Pavel Tikhomirov <[email protected]>
Cc Hannes Reinecke <[email protected]>
Cc Johannes Thumshirn <[email protected]>
---
 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(-)
drivers/scsi/hosts.c +0 -3
@@ -328,8 +328,6 @@ static void scsi_host_dev_release(struct
 	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
 	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)
drivers/scsi/scsi_error.c +3 -2
@@ -222,7 +222,8 @@ static void scsi_eh_reset(struct scsi_cm
 
 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);
@@ -258,7 +259,7 @@ void scsi_eh_scmd_add(struct scsi_cmnd *
 	 * 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);
 }
 
 /**
drivers/scsi/scsi_lib.c +2 -0
@@ -670,6 +670,7 @@ static bool scsi_end_request(struct requ
 	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 @@ void scsi_initialize_rq(struct request *
 	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;
 }
include/scsi/scsi_cmnd.h +3 -0
@@ -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 */
 
 	/*
include/scsi/scsi_host.h +0 -2
@@ -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;
 

Patches currently in stable-queue which might be from [email protected] are

queue-4.14/scsi-core-avoid-that-ata-error-handling-can-trigger-a-kernel-hang-or-oops.patch