summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Collins <bcollins@ubuntu.com>2012-06-11 20:44:44 +0200
committerJames Bottomley <JBottomley@Parallels.com>2012-07-20 09:58:44 +0200
commit30002f1c02ada69342443e7ed5ee9118feb89510 (patch)
tree369369427cbbfd3b1bdeabd7aa7ed8355f1e53e9
parent[SCSI] aacraid: Better handling of in-flight events on thread stop (diff)
downloadlinux-30002f1c02ada69342443e7ed5ee9118feb89510.tar.xz
linux-30002f1c02ada69342443e7ed5ee9118feb89510.zip
[SCSI] aacraid: Relax the tight timeout loop on fib commands
The loop that waited for syncronous fib commands was causing a CPU stall when a timeout actually occured. 1) Switch to using a more accurate timeout mechanism. 2) Do not pace the loop with udelay(). Use cpu_relax() to allow for scheduling to occur. Signed-off-by: Ben Collins <bcollins@ubuntu.com> Acked-by: Achim Leubner <Achim_Leubner@pmc-sierra.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/aacraid/commsup.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 4b32ca442433..906a5013edae 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -564,10 +564,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
* functioning because an interrupt routing or other
* hardware failure has occurred.
*/
- unsigned long count = 36000000L; /* 3 minutes */
+ unsigned long timeout = jiffies + (180 * HZ); /* 3 minutes */
while (down_trylock(&fibptr->event_wait)) {
int blink;
- if (--count == 0) {
+ if (time_is_before_eq_jiffies(timeout)) {
struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue];
spin_lock_irqsave(q->lock, qflags);
q->numpending--;
@@ -588,7 +588,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
}
return -EFAULT;
}
- udelay(5);
+ /* We used to udelay() here but that absorbed
+ * a CPU when a timeout occured. Not very
+ * useful. */
+ cpu_relax();
}
} else if (down_interruptible(&fibptr->event_wait)) {
/* Do nothing ... satisfy