summaryrefslogtreecommitdiff
path: root/drivers/ide
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2010-04-01 00:11:59 +0400
committerDavid S. Miller <davem@davemloft.net>2010-04-01 12:31:13 +0400
commit6072f7491f5ef391a575e18a1165e72a3eef1601 (patch)
tree8d15e02b391f89bc518d6981a9325244d464614b /drivers/ide
parent9ce41aed0d392246eb788786253f242e829fd5e1 (diff)
downloadlinux-6072f7491f5ef391a575e18a1165e72a3eef1601.tar.xz
ide: Requeue request after DMA timeout
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 8f6205cd572fece673da0255d74843680f67f879 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>
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/ide-dma.c1
-rw-r--r--drivers/ide/ide-io.c2
2 files changed, 2 insertions, 1 deletions
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index ee58c88dee5a..fd40a8116574 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -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;
}
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index db96138fefcd..172ac9218154 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -566,7 +566,7 @@ plug_device_2:
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;