patch-2.3.43 linux/drivers/scsi/scsi_error.c

Next file: linux/drivers/scsi/scsi_ioctl.c
Previous file: linux/drivers/scsi/scsi.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.42/linux/drivers/scsi/scsi_error.c linux/drivers/scsi/scsi_error.c
@@ -972,9 +972,13 @@
 		 * When the low level driver returns DID_SOFT_ERROR,
 		 * it is responsible for keeping an internal retry counter 
 		 * in order to avoid endless loops (DB)
+		 *
+		 * Actually this is a bug in this function here.  We should
+		 * be mindful of the maximum number of retries specified
+		 * and not get stuck in a loop.
 		 */
 	case DID_SOFT_ERROR:
-		return NEEDS_RETRY;
+		goto maybe_retry;
 
 	case DID_BUS_BUSY:
 	case DID_PARITY:
@@ -1830,6 +1834,8 @@
          */
         if( host->loaded_as_module ) {
 	siginitsetinv(&current->blocked, SHUTDOWN_SIGS);
+	} else {
+	siginitsetinv(&current->blocked, 0);
         }
 
 	lock_kernel();
@@ -1865,13 +1871,20 @@
 		 * trying to unload a module.
 		 */
 		SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler sleeping\n"));
-                if( host->loaded_as_module ) {
-		down_interruptible(&sem);
 
-		if (signal_pending(current))
-			break;
-                } else {
-                        down(&sem);
+		/*
+		 * Note - we always use down_interruptible with the semaphore
+		 * even if the module was loaded as part of the kernel.  The
+		 * reason is that down() will cause this thread to be counted
+		 * in the load average as a running process, and down
+		 * interruptible doesn't.  Given that we need to allow this
+		 * thread to die if the driver was loaded as a module, using
+		 * semaphores isn't unreasonable.
+		 */
+		down_interruptible(&sem);
+		if( host->loaded_as_module ) {
+			if (signal_pending(current))
+				break;
                 }
 
 		SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler waking up\n"));

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)