diff options
| -rw-r--r-- | block/blk-core.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 3c923a7aeb56..ce7fbf8d85a6 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
| @@ -361,9 +361,10 @@ EXPORT_SYMBOL(blk_put_queue); | |||
| 361 | */ | 361 | */ |
| 362 | void blk_drain_queue(struct request_queue *q, bool drain_all) | 362 | void blk_drain_queue(struct request_queue *q, bool drain_all) |
| 363 | { | 363 | { |
| 364 | int i; | ||
| 365 | |||
| 364 | while (true) { | 366 | while (true) { |
| 365 | bool drain = false; | 367 | bool drain = false; |
| 366 | int i; | ||
| 367 | 368 | ||
| 368 | spin_lock_irq(q->queue_lock); | 369 | spin_lock_irq(q->queue_lock); |
| 369 | 370 | ||
| @@ -408,6 +409,18 @@ void blk_drain_queue(struct request_queue *q, bool drain_all) | |||
| 408 | break; | 409 | break; |
| 409 | msleep(10); | 410 | msleep(10); |
| 410 | } | 411 | } |
| 412 | |||
| 413 | /* | ||
| 414 | * With queue marked dead, any woken up waiter will fail the | ||
| 415 | * allocation path, so the wakeup chaining is lost and we're | ||
| 416 | * left with hung waiters. We need to wake up those waiters. | ||
| 417 | */ | ||
| 418 | if (q->request_fn) { | ||
| 419 | spin_lock_irq(q->queue_lock); | ||
| 420 | for (i = 0; i < ARRAY_SIZE(q->rq.wait); i++) | ||
| 421 | wake_up_all(&q->rq.wait[i]); | ||
| 422 | spin_unlock_irq(q->queue_lock); | ||
| 423 | } | ||
| 411 | } | 424 | } |
| 412 | 425 | ||
| 413 | /** | 426 | /** |
