- ieee1394-sbp2-prevent-rare-deadlock-in-shutdown.patch removed from -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled

     ieee1394: sbp2: prevent rare deadlock in shutdown

has been removed from the -mm tree.  Its filename is

     ieee1394-sbp2-prevent-rare-deadlock-in-shutdown.patch

This patch was dropped because it was merged into mainline or a subsystem tree

------------------------------------------------------
Subject: ieee1394: sbp2: prevent rare deadlock in shutdown
From: Stefan Richter <stefanr@xxxxxxxxxxxxxxxxx>

Scsi_remove_device() may go into uninterruptible sleep if blocked.  Therefore
sbp2_remove() unblocks the Scsi_Host before the device is requested to be
removed.  But there could be another 1394 bus reset after that which would
block the host again.  The 1394 subsystem won't call sbp2_update()
concurrently to sbp2_remove(), which is why there is no chance for
sbp2_remove() to be unblocked by sbp2_update().

The fix is to tell sbp2's bus reset handler when a device is to be shut down
so that it skips scsi_block_requests() on that host.  As before, any new
commands after a reset without reconnect will be failed quickly by
sbp2scsi_queuecommand().

In the long term, means to go without scsi_block_requests() should be found.

Signed-off-by: Stefan Richter <stefanr@xxxxxxxxxxxxxxxxx>
Cc: Jody McIntyre <scjody@xxxxxxxxxxxxxx>
Cc: Ben Collins <bcollins@xxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 drivers/ieee1394/sbp2.c |   21 +++++++++++----------
 drivers/ieee1394/sbp2.h |    9 ++++++++-
 2 files changed, 19 insertions(+), 11 deletions(-)

diff -puN drivers/ieee1394/sbp2.c~ieee1394-sbp2-prevent-rare-deadlock-in-shutdown drivers/ieee1394/sbp2.c
--- a/drivers/ieee1394/sbp2.c~ieee1394-sbp2-prevent-rare-deadlock-in-shutdown
+++ a/drivers/ieee1394/sbp2.c
@@ -478,7 +478,7 @@ static void sbp2util_notify_fetch_agent(
 	 * There is a small window after a bus reset within which the node
 	 * entry's generation is current but the reconnect wasn't completed.
 	 */
-	if (atomic_read(&scsi_id->unfinished_reset))
+	if (unlikely(atomic_read(&scsi_id->state) == SBP2LU_STATE_IN_RESET))
 		return;
 
 	if (hpsb_node_write(scsi_id->ne,
@@ -489,7 +489,7 @@ static void sbp2util_notify_fetch_agent(
 	 * Now accept new SCSI commands, unless a bus reset happended during
 	 * hpsb_node_write.
 	 */
-	if (!atomic_read(&scsi_id->unfinished_reset))
+	if (likely(atomic_read(&scsi_id->state) != SBP2LU_STATE_IN_RESET))
 		scsi_unblock_requests(scsi_id->scsi_host);
 }
 
@@ -756,7 +756,7 @@ static int sbp2_remove(struct device *de
 			sbp2scsi_complete_all_commands(scsi_id, DID_NO_CONNECT);
 		/* scsi_remove_device() will trigger shutdown functions of SCSI
 		 * highlevel drivers which would deadlock if blocked. */
-		atomic_set(&scsi_id->unfinished_reset, 0);
+		atomic_set(&scsi_id->state, SBP2LU_STATE_IN_SHUTDOWN);
 		scsi_unblock_requests(scsi_id->scsi_host);
 	}
 	sdev = scsi_id->sdev;
@@ -811,7 +811,7 @@ static int sbp2_update(struct unit_direc
 	/* Accept new commands unless there was another bus reset in the
 	 * meantime. */
 	if (hpsb_node_entry_valid(scsi_id->ne)) {
-		atomic_set(&scsi_id->unfinished_reset, 0);
+		atomic_set(&scsi_id->state, SBP2LU_STATE_RUNNING);
 		scsi_unblock_requests(scsi_id->scsi_host);
 	}
 	return 0;
@@ -842,7 +842,7 @@ static struct scsi_id_instance_data *sbp
 	INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed);
 	INIT_LIST_HEAD(&scsi_id->scsi_list);
 	spin_lock_init(&scsi_id->sbp2_command_orb_lock);
-	atomic_set(&scsi_id->unfinished_reset, 0);
+	atomic_set(&scsi_id->state, SBP2LU_STATE_RUNNING);
 	INIT_WORK(&scsi_id->protocol_work, NULL, NULL);
 
 	ud->device.driver_data = scsi_id;
@@ -926,13 +926,14 @@ static void sbp2_host_reset(struct hpsb_
 	struct scsi_id_instance_data *scsi_id;
 
 	hi = hpsb_get_hostinfo(&sbp2_highlevel, host);
-
-	if (hi) {
-		list_for_each_entry(scsi_id, &hi->scsi_ids, scsi_list) {
-			atomic_set(&scsi_id->unfinished_reset, 1);
+	if (!hi)
+		return;
+	list_for_each_entry(scsi_id, &hi->scsi_ids, scsi_list)
+		if (likely(atomic_read(&scsi_id->state) !=
+			   SBP2LU_STATE_IN_SHUTDOWN)) {
+			atomic_set(&scsi_id->state, SBP2LU_STATE_IN_RESET);
 			scsi_block_requests(scsi_id->scsi_host);
 		}
-	}
 }
 
 /*
diff -puN drivers/ieee1394/sbp2.h~ieee1394-sbp2-prevent-rare-deadlock-in-shutdown drivers/ieee1394/sbp2.h
--- a/drivers/ieee1394/sbp2.h~ieee1394-sbp2-prevent-rare-deadlock-in-shutdown
+++ a/drivers/ieee1394/sbp2.h
@@ -347,10 +347,17 @@ struct scsi_id_instance_data {
 	/* Device specific workarounds/brokeness */
 	unsigned workarounds;
 
-	atomic_t unfinished_reset;
+	atomic_t state;
 	struct work_struct protocol_work;
 };
 
+/* For use in scsi_id_instance_data.state */
+enum sbp2lu_state_types {
+	SBP2LU_STATE_RUNNING,		/* all normal */
+	SBP2LU_STATE_IN_RESET,		/* between bus reset and reconnect */
+	SBP2LU_STATE_IN_SHUTDOWN	/* when sbp2_remove was called */
+};
+
 /* Sbp2 host data structure (one per IEEE1394 host) */
 struct sbp2scsi_host_info {
 	struct hpsb_host *host;		/* IEEE1394 host */
_

Patches currently in -mm which might be from stefanr@xxxxxxxxxxxxxxxxx are

origin.patch
git-ieee1394.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux