aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/hpsa.c
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2013-09-23 14:34:17 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-12-19 10:38:56 -0500
commit396883e292ebe1e14ded99fd8b26be500926f055 (patch)
tree71cd4a71008293204144136a024dd551738c1794 /drivers/scsi/hpsa.c
parent0390f0c0dfb540149d7369276b17ec53caf506cb (diff)
[SCSI] hpsa: prevent stalled i/o
If a fifo full condition is encountered, i/o requests will stack up in the h->reqQ queue. The only thing which empties this queue is start_io, which only gets called when new i/o requests come in. If none are forthcoming, i/o in h->reqQ will be stalled. To fix this, whenever fifo full condition is encountered, this is recorded, and the interrupt handler examines this to see if a fifo full condition was recently encountered when a command completes and will call start_io to prevent i/o's in h->reqQ from getting stuck. I've only ever seen this problem occur when running specialized test programs that pound on the the CCISS_PASSTHRU ioctl. Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r--drivers/scsi/hpsa.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9acfce3bbe78..9fbc6f9120ac 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3483,9 +3483,11 @@ static void start_io(struct ctlr_info *h)
3483 c = list_entry(h->reqQ.next, struct CommandList, list); 3483 c = list_entry(h->reqQ.next, struct CommandList, list);
3484 /* can't do anything if fifo is full */ 3484 /* can't do anything if fifo is full */
3485 if ((h->access.fifo_full(h))) { 3485 if ((h->access.fifo_full(h))) {
3486 h->fifo_recently_full = 1;
3486 dev_warn(&h->pdev->dev, "fifo full\n"); 3487 dev_warn(&h->pdev->dev, "fifo full\n");
3487 break; 3488 break;
3488 } 3489 }
3490 h->fifo_recently_full = 0;
3489 3491
3490 /* Get the first entry from the Request Q */ 3492 /* Get the first entry from the Request Q */
3491 removeQ(c); 3493 removeQ(c);
@@ -3539,15 +3541,41 @@ static inline int bad_tag(struct ctlr_info *h, u32 tag_index,
3539static inline void finish_cmd(struct CommandList *c) 3541static inline void finish_cmd(struct CommandList *c)
3540{ 3542{
3541 unsigned long flags; 3543 unsigned long flags;
3544 int io_may_be_stalled = 0;
3545 struct ctlr_info *h = c->h;
3542 3546
3543 spin_lock_irqsave(&c->h->lock, flags); 3547 spin_lock_irqsave(&h->lock, flags);
3544 removeQ(c); 3548 removeQ(c);
3545 spin_unlock_irqrestore(&c->h->lock, flags); 3549
3550 /*
3551 * Check for possibly stalled i/o.
3552 *
3553 * If a fifo_full condition is encountered, requests will back up
3554 * in h->reqQ. This queue is only emptied out by start_io which is
3555 * only called when a new i/o request comes in. If no i/o's are
3556 * forthcoming, the i/o's in h->reqQ can get stuck. So we call
3557 * start_io from here if we detect such a danger.
3558 *
3559 * Normally, we shouldn't hit this case, but pounding on the
3560 * CCISS_PASSTHRU ioctl can provoke it. Only call start_io if
3561 * commands_outstanding is low. We want to avoid calling
3562 * start_io from in here as much as possible, and esp. don't
3563 * want to get in a cycle where we call start_io every time
3564 * through here.
3565 */
3566 if (unlikely(h->fifo_recently_full) &&
3567 h->commands_outstanding < 5)
3568 io_may_be_stalled = 1;
3569
3570 spin_unlock_irqrestore(&h->lock, flags);
3571
3546 dial_up_lockup_detection_on_fw_flash_complete(c->h, c); 3572 dial_up_lockup_detection_on_fw_flash_complete(c->h, c);
3547 if (likely(c->cmd_type == CMD_SCSI)) 3573 if (likely(c->cmd_type == CMD_SCSI))
3548 complete_scsi_command(c); 3574 complete_scsi_command(c);
3549 else if (c->cmd_type == CMD_IOCTL_PEND) 3575 else if (c->cmd_type == CMD_IOCTL_PEND)
3550 complete(c->waiting); 3576 complete(c->waiting);
3577 if (unlikely(io_may_be_stalled))
3578 start_io(h);
3551} 3579}
3552 3580
3553static inline u32 hpsa_tag_contains_index(u32 tag) 3581static inline u32 hpsa_tag_contains_index(u32 tag)