diff options
Diffstat (limited to 'mm/backing-dev.c')
-rw-r--r-- | mm/backing-dev.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 1065b715ef64..67a33a5a1a93 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -604,10 +604,14 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi) | |||
604 | 604 | ||
605 | /* | 605 | /* |
606 | * Finally, kill the kernel threads. We don't need to be RCU | 606 | * Finally, kill the kernel threads. We don't need to be RCU |
607 | * safe anymore, since the bdi is gone from visibility. | 607 | * safe anymore, since the bdi is gone from visibility. Force |
608 | * unfreeze of the thread before calling kthread_stop(), otherwise | ||
609 | * it would never exet if it is currently stuck in the refrigerator. | ||
608 | */ | 610 | */ |
609 | list_for_each_entry(wb, &bdi->wb_list, list) | 611 | list_for_each_entry(wb, &bdi->wb_list, list) { |
612 | wb->task->flags &= ~PF_FROZEN; | ||
610 | kthread_stop(wb->task); | 613 | kthread_stop(wb->task); |
614 | } | ||
611 | } | 615 | } |
612 | 616 | ||
613 | /* | 617 | /* |
@@ -628,6 +632,8 @@ static void bdi_prune_sb(struct backing_dev_info *bdi) | |||
628 | void bdi_unregister(struct backing_dev_info *bdi) | 632 | void bdi_unregister(struct backing_dev_info *bdi) |
629 | { | 633 | { |
630 | if (bdi->dev) { | 634 | if (bdi->dev) { |
635 | bdi_prune_sb(bdi); | ||
636 | |||
631 | if (!bdi_cap_flush_forker(bdi)) | 637 | if (!bdi_cap_flush_forker(bdi)) |
632 | bdi_wb_shutdown(bdi); | 638 | bdi_wb_shutdown(bdi); |
633 | bdi_debug_unregister(bdi); | 639 | bdi_debug_unregister(bdi); |
@@ -697,7 +703,6 @@ void bdi_destroy(struct backing_dev_info *bdi) | |||
697 | spin_unlock(&inode_lock); | 703 | spin_unlock(&inode_lock); |
698 | } | 704 | } |
699 | 705 | ||
700 | bdi_prune_sb(bdi); | ||
701 | bdi_unregister(bdi); | 706 | bdi_unregister(bdi); |
702 | 707 | ||
703 | for (i = 0; i < NR_BDI_STAT_ITEMS; i++) | 708 | for (i = 0; i < NR_BDI_STAT_ITEMS; i++) |