mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-04 02:06:43 +07:00
block: fix drain_all condition in blk_drain_queue()
When trying to drain all requests, blk_drain_queue() checked only q->rq.count[]; however, this only tracks REQ_ALLOCED requests. This patch updates blk_drain_queue() such that it looks at all the counters and queues so that request_queue is actually empty on completion. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
34f6055c80
commit
481a7d6479
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user