Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3369

kernel-2.6.18-194.11.1.el5.src.rpm

From: Takahiro Yasui <tyasui@redhat.com>
Date: Fri, 20 Nov 2009 20:39:45 -0500
Subject: [scsi] disable state transition from OFFLINE to RUNNING
Message-id: <4B06FE91.1090700@redhat.com>
Patchwork-id: 21459
O-Subject: [RHEL5.5 PATCH] BZ#516934: disable scsi state transition from OFFLINE
	to RUNNING
Bugzilla: 516934
RH-Acked-by: David Milburn <dmilburn@redhat.com>

BZ#:
----
  https://bugzilla.redhat.com/show_bug.cgi?id=516934

Description:
-----------
  This patch prevents repeated timeouts on the same device by disabling
  the state transition from SDEV_OFFLINE to SDEV_RUNNING in the
  scsi_internal_device_unblock() function.

  scsi timeout on two or more devices may cause extremely long execution
  time for user applications because SDEV_OFFLINE state is changed to
  SDEV_RUNNING state during scsi error recovery procedures triggered by
  a bus reset or a host reset of scsi LLD, and scsi timeout can happens
  on the same devices many times.

  This happens because scsi_internal_device_unblock() changes device's
  state to SDEV_RUNNING even if a device in other states than SDEV_BLOCK,
  while the following transition is required in this function.

    SDEV_BLOCK -> SDEV_RUNNING

  Otherwise, it returns -EINVAL.

  Notes:
  The current RHEL5 kernel doesn't have the state SDEV_CREATED_BLOCK.
  In this patch, the transition from SDEV_CREATED_BLOCK to SDEV_CREATED
  is removed from the upstream patch.

Upstream status:
----------------
  Merged in 2.6.31-rc1
  http://git.kernel.org/linus/5c10e63c943b4c67561ddc6bf61e01d4141f881f

Brew Build:
-----------
  https://brewweb.devel.redhat.com/taskinfo?taskID=2085751

Test status:
------------
  Patch was tested with kernel-2.6.18-173.el5 on x86 Server, and offline
  devices were not activated after timeouts happened on other devices.

Signed-off-by: Takahiro Yasui <tyasui@redhat.com>

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 7a26d25..5d412ad 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2395,16 +2395,16 @@ int
 scsi_internal_device_unblock(struct scsi_device *sdev)
 {
 	request_queue_t *q = sdev->request_queue; 
-	int err;
 	unsigned long flags;
 	
 	/* 
 	 * Try to transition the scsi device to SDEV_RUNNING
 	 * and goose the device queue if successful.  
 	 */
-	err = scsi_device_set_state(sdev, SDEV_RUNNING);
-	if (err)
-		return err;
+	if (sdev->sdev_state == SDEV_BLOCK)
+		sdev->sdev_state = SDEV_RUNNING;
+	else
+		return -EINVAL;
 
 	spin_lock_irqsave(q->queue_lock, flags);
 	blk_start_queue(q);