Skip to content

Commit

Permalink
ide: Requeue request after DMA timeout
Browse files Browse the repository at this point in the history
I noticed that my KVM virtual machines were experiencing IDE
issues resulting in processes stuck on waiting for buffers to
complete.

The root cause is of course race conditions in the ancient qemu
backend that I'm using.  However, the fact that the guest isn't
recovering is a bug.

I've tracked it down to the change made last year to dequeue
requests at the start rather than at the end in the IDE layer.

commit 8f6205c
Author: Tejun Heo <tj@kernel.org>
Date:   Fri May 8 11:53:59 2009 +0900

    ide: dequeue in-flight request

The problem is that the function ide_dma_timeout_retry does not
requeue the current request, causing one request to be lost for
each DMA timeout.

This patch fixes this by requeueing the request.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Herbert Xu authored and David S. Miller committed Apr 1, 2010
1 parent 9ce41ae commit 6072f74
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 1 deletion.
1 change: 1 addition & 0 deletions drivers/ide/ide-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
if (rq) {
hwif->rq = NULL;
rq->errors = 0;
ide_requeue_and_plug(drive, rq);
}
return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/ide/ide-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ void do_ide_request(struct request_queue *q)
blk_plug_device(q);
}

static void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
{
struct request_queue *q = drive->queue;
unsigned long flags;
Expand Down
1 change: 1 addition & 0 deletions include/linux/ide.h
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,7 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
extern void ide_timer_expiry(unsigned long);
extern irqreturn_t ide_intr(int irq, void *dev_id);
extern void do_ide_request(struct request_queue *);
extern void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq);

void ide_init_disk(struct gendisk *, ide_drive_t *);

Expand Down

0 comments on commit 6072f74

Please sign in to comment.