Messages in this thread Patch in this message | | | Date | Thu, 3 Dec 1998 13:50:55 +0100 (CET) | From | Andrea Arcangeli <> | Subject | Re: scsi code and jiffy wraps |
| |
On Thu, 3 Dec 1998, Andrea Arcangeli wrote:
>in. It avoids that the scsi system hangs the machine after ~0UL jiffies >from the latest scsi reset. I tested it in the only way I was able to do.
Woops, please reject/forget the scsi-2.1.130 patch in the last email. I fixed a little bug + a cleanup and I rediffed against 2.1.131:
Index: linux/drivers/scsi/scsi.c diff -u linux/drivers/scsi/scsi.c:1.1.1.1 linux/drivers/scsi/scsi.c:1.1.1.1.2.3 --- linux/drivers/scsi/scsi.c:1.1.1.1 Fri Nov 20 00:02:39 1998 +++ linux/drivers/scsi/scsi.c Thu Dec 3 12:29:40 1998 @@ -30,6 +30,8 @@ * Leonard N. Zubkoff <lnz@dandelion.com> * * Converted cli() code to spinlocks, Ingo Molnar + * + * Jiffies wrap fixes (host->resetting), 3 Dec 1998 Andrea Arcangeli */ #include <linux/config.h> @@ -1297,7 +1299,7 @@ */ timeout = host->last_reset + MIN_RESET_DELAY; - if (jiffies < timeout) { + if (host->resetting && time_before(jiffies, timeout)) { int ticks_remaining = timeout - jiffies; /* * NOTE: This may be executed from within an interrupt @@ -1310,7 +1312,7 @@ */ spin_unlock_irq(&io_request_lock); while (--ticks_remaining >= 0) mdelay(1+999/HZ); - host->last_reset = jiffies - MIN_RESET_DELAY; + host->resetting = 0; spin_lock_irq(&io_request_lock); } @@ -1367,7 +1369,7 @@ #ifdef DEBUG_DELAY clock = jiffies + 4 * HZ; spin_unlock_irq(&io_request_lock); - while (jiffies < clock) barrier(); + while (time_before(jiffies, clock)) barrier(); spin_lock_irq(&io_request_lock); printk("done(host = %d, result = %04x) : routine at %p\n", host->host_no, temp, host->hostt->command); Index: linux/drivers/scsi/hosts.c diff -u linux/drivers/scsi/hosts.c:1.1.1.1 linux/drivers/scsi/hosts.c:1.1.1.1.2.5 --- linux/drivers/scsi/hosts.c:1.1.1.1 Fri Nov 20 00:02:39 1998 +++ linux/drivers/scsi/hosts.c Thu Dec 3 12:29:39 1998 @@ -7,6 +7,8 @@ * Subsequent revisions: Eric Youngdale * * <drew@colorado.edu> + * + * Jiffies wrap fixes (host->resetting), 3 Dec 1998 Andrea Arcangeli */ @@ -581,7 +583,8 @@ next_scsi_host++; retval->host_queue = NULL; retval->host_wait = NULL; - retval->last_reset = 0; + retval->resetting = 0; + /* retval->last_reset don' t need to be set because resetting is 0 -arca */ retval->irq = 0; retval->dma_channel = 0xff; Index: linux/drivers/scsi/hosts.h diff -u linux/drivers/scsi/hosts.h:1.1.1.1 linux/drivers/scsi/hosts.h:1.1.1.1.2.2 --- linux/drivers/scsi/hosts.h:1.1.1.1 Fri Nov 20 00:02:39 1998 +++ linux/drivers/scsi/hosts.h Thu Dec 3 12:29:40 1998 @@ -14,6 +14,8 @@ * * Further modified by Eric Youngdale to support multiple host adapters * of the same type. + * + * Jiffies wrap fixes (host->resetting), 3 Dec 1998 Andrea Arcangeli */ #ifndef _HOSTS_H @@ -320,6 +322,7 @@ /* public: */ unsigned short extra_bytes; unsigned short host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */ + int resetting; /* if set, it means that last_reset is a valid value */ unsigned long last_reset; Index: linux/drivers/scsi/scsi_error.c diff -u linux/drivers/scsi/scsi_error.c:1.1.1.1 linux/drivers/scsi/scsi_error.c:1.1.1.1.2.1 --- linux/drivers/scsi/scsi_error.c:1.1.1.1 Fri Nov 20 00:02:54 1998 +++ linux/drivers/scsi/scsi_error.c Fri Nov 20 00:15:31 1998 @@ -142,7 +142,6 @@ SCSI_LOG_ERROR_RECOVERY(5,printk("Clearing timer for command %p\n", SCset)); SCset->eh_timeout.data = (unsigned long) NULL; - SCset->eh_timeout.expires = 0; SCset->eh_timeout.function = NULL; return rtn; Index: linux/drivers/scsi/scsi_obsolete.c diff -u linux/drivers/scsi/scsi_obsolete.c:1.1.1.2 linux/drivers/scsi/scsi_obsolete.c:1.1.1.1.2.5 --- linux/drivers/scsi/scsi_obsolete.c:1.1.1.2 Thu Dec 3 12:53:28 1998 +++ linux/drivers/scsi/scsi_obsolete.c Thu Dec 3 14:01:03 1998 @@ -604,21 +604,18 @@ printk("In MAYREDO, allowing %d retries, have %d\n", SCpnt->allowed, SCpnt->retries); #endif - if ((++SCpnt->retries) < SCpnt->allowed) - { - if ((SCpnt->retries >= (SCpnt->allowed >> 1)) - /* FIXME: last_reset == 0 is allowed */ - && time_after(jiffies, SCpnt->host->last_reset - + MIN_RESET_PERIOD) - && !(SCpnt->flags & WAS_RESET)) - { - printk("scsi%d channel %d : resetting for second half of retries.\n", - SCpnt->host->host_no, SCpnt->channel); - scsi_reset(SCpnt, SCSI_RESET_SYNCHRONOUS); - break; - } - - } + if (++SCpnt->retries < SCpnt->allowed && + SCpnt->retries >= (SCpnt->allowed >> 1) + && !(SCpnt->host->resetting && + time_before(jiffies, SCpnt->host->last_reset + + MIN_RESET_PERIOD)) + && !(SCpnt->flags & WAS_RESET)) + { + printk("scsi%d channel %d : resetting for second half of retries.\n", + SCpnt->host->host_no, SCpnt->channel); + scsi_reset(SCpnt, SCSI_RESET_SYNCHRONOUS); + break; + } else { status = CMD_FINISHED; @@ -935,6 +932,12 @@ } host->last_reset = jiffies; + host->resetting = 1; + /* + * I suppose that the host reset callback will not play + * with the resetting field. We have just set the resetting + * flag here. -arca + */ temp = host->hostt->reset(SCpnt, reset_flags); /* This test allows the driver to introduce an additional bus @@ -953,7 +956,13 @@ { if (!host->block) host->host_busy++; host->last_reset = jiffies; + host->resetting = 1; SCpnt->flags |= (WAS_RESET | IS_RESETTING); + /* + * I suppose that the host reset callback will not play + * with the resetting field. We have just set the resetting + * flag here. -arca + */ temp = host->hostt->reset(SCpnt, reset_flags); if (time_before(host->last_reset, jiffies) || (time_after(host->last_reset, jiffies + 20 * HZ))) Andrea Arcangeli
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |