From 940383988f16b038dcbcd30de3c50e2f416cc28d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 14 Dec 2011 00:33:37 +0100 Subject: [PATCH] --- yaml --- r: 285095 b: refs/heads/master c: 481a7d64790cd7ca61a8bbcbd9d017ce58e6fe39 h: refs/heads/master i: 285093: 352af872368f1d67464120b40969366e0294532a 285091: bcdd0b467f9abe10562ce4472a6aa80b9657122f 285087: 8f85c23d6dc236973d3ddd375492cb37837da360 v: v3 --- [refs] | 2 +- trunk/block/blk-core.c | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index 7e766ba7a028..f970c70cad4f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 34f6055c80285e4efb3f602a9119db75239744dc +refs/heads/master: 481a7d64790cd7ca61a8bbcbd9d017ce58e6fe39 diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index b5ed4f4a8d96..c37e9e7c9d07 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -358,7 +358,8 @@ EXPORT_SYMBOL(blk_put_queue); void blk_drain_queue(struct request_queue *q, bool drain_all) { while (true) { - int nr_rqs; + bool drain = false; + int i; spin_lock_irq(q->queue_lock); @@ -368,14 +369,25 @@ void blk_drain_queue(struct request_queue *q, bool drain_all) __blk_run_queue(q); - if (drain_all) - nr_rqs = q->rq.count[0] + q->rq.count[1]; - else - nr_rqs = q->rq.elvpriv; + drain |= q->rq.elvpriv; + + /* + * Unfortunately, requests are queued at and tracked from + * multiple places and there's no single counter which can + * be drained. Check all the queues and counters. + */ + if (drain_all) { + drain |= !list_empty(&q->queue_head); + for (i = 0; i < 2; i++) { + drain |= q->rq.count[i]; + drain |= q->in_flight[i]; + drain |= !list_empty(&q->flush_queue[i]); + } + } spin_unlock_irq(q->queue_lock); - if (!nr_rqs) + if (!drain) break; msleep(10); }