Skip to content

Commit

Permalink
ide: clean up timed out request handling
Browse files Browse the repository at this point in the history
8f6205c introduced a bug where a
timed out DMA request is never requeued and lost.
6072f74 fixed this by making
ide_dma_timeout_retry() requeue the request itself.  While the fix is
correct, it makes DMA and non-DMA paths asymmetric regarding how the
in flight request is requeued.

As long as hwif->rq is set, the IDE driver is assuming ownership of
the request and the request should either be completed or requeued
when clearing hwif->rq.  In the timeout path, the ide driver holds
onto the request as long as the recovery action (ie. reset) is in
progress and clears it after the state machine is stopped (ide_stopped
return), so the existing requeueing logic is correct.  The bug
occurred because ide_dma_timeout_retry() explicitly clears hwif->rq
without requeueing it.

ide_dma_timeout_retry() is called only by ide_timer_expiry() and
returns ide_started only when ide_error() would return it - ie. after
reset state machine has started in which case the state machine will
eventually end up executing the ide_stopped path in ide_timer_expiry()
after reset protocol is complete.  So, there is no need to clear
hwif->rq from ide_dma_timeout_retry().  ide_timer_expiry() will handle
it the same way as PIO timeout path.

Kill hwif->rq clearing and requeueing from ide_dma_timeout_retry() and
let ide_timer_expiry() deal with it.  The end result should remain the
same.

grepping shows ide_dma_timeout_retry() is the only site which clears
hwif->rq without taking care of the request, so there shouldn't be
similar fallouts.

Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Tejun Heo authored and David S. Miller committed Oct 26, 2010
1 parent bbe54d7 commit dd8717d
Showing 1 changed file with 3 additions and 8 deletions.
11 changes: 3 additions & 8 deletions drivers/ide/ide-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,6 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
ide_hwif_t *hwif = drive->hwif;
const struct ide_dma_ops *dma_ops = hwif->dma_ops;
struct ide_cmd *cmd = &hwif->cmd;
struct request *rq;
ide_startstop_t ret = ide_stopped;

/*
Expand Down Expand Up @@ -487,14 +486,10 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
ide_dma_off_quietly(drive);

/*
* un-busy drive etc and make sure request is sane
* make sure request is sane
*/
rq = hwif->rq;
if (rq) {
hwif->rq = NULL;
rq->errors = 0;
ide_requeue_and_plug(drive, rq);
}
if (hwif->rq)
hwif->rq->errors = 0;
return ret;
}

Expand Down

0 comments on commit dd8717d

Please sign in to comment.