diff options
author | Ben Collins <bcollins@ubuntu.com> | 2012-06-11 14:44:44 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-07-20 03:58:44 -0400 |
commit | 30002f1c02ada69342443e7ed5ee9118feb89510 (patch) | |
tree | 369369427cbbfd3b1bdeabd7aa7ed8355f1e53e9 /drivers | |
parent | 361ee9c3f3839d6cbd306b5bd34292e0848ecfdc (diff) |
[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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 9 |
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, | |||
564 | * functioning because an interrupt routing or other | 564 | * functioning because an interrupt routing or other |
565 | * hardware failure has occurred. | 565 | * hardware failure has occurred. |
566 | */ | 566 | */ |
567 | unsigned long count = 36000000L; /* 3 minutes */ | 567 | unsigned long timeout = jiffies + (180 * HZ); /* 3 minutes */ |
568 | while (down_trylock(&fibptr->event_wait)) { | 568 | while (down_trylock(&fibptr->event_wait)) { |
569 | int blink; | 569 | int blink; |
570 | if (--count == 0) { | 570 | if (time_is_before_eq_jiffies(timeout)) { |
571 | struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue]; | 571 | struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue]; |
572 | spin_lock_irqsave(q->lock, qflags); | 572 | spin_lock_irqsave(q->lock, qflags); |
573 | q->numpending--; | 573 | q->numpending--; |
@@ -588,7 +588,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
588 | } | 588 | } |
589 | return -EFAULT; | 589 | return -EFAULT; |
590 | } | 590 | } |
591 | udelay(5); | 591 | /* We used to udelay() here but that absorbed |
592 | * a CPU when a timeout occured. Not very | ||
593 | * useful. */ | ||
594 | cpu_relax(); | ||
592 | } | 595 | } |
593 | } else if (down_interruptible(&fibptr->event_wait)) { | 596 | } else if (down_interruptible(&fibptr->event_wait)) { |
594 | /* Do nothing ... satisfy | 597 | /* Do nothing ... satisfy |