diff options
author | Jan Kara <jack@suse.cz> | 2017-03-22 20:36:56 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2017-03-22 22:11:27 -0400 |
commit | e8cb72b322cf4a729633b7e2080fbeab477f6ea2 (patch) | |
tree | 1bf1accf057f327631748d40be3fd4b0877b5515 /mm/backing-dev.c | |
parent | 810df54a64fb7841d6511f67818f3e1589c249a2 (diff) |
bdi: Unify bdi->wb_list handling for root wb_writeback
Currently root wb_writeback structure is added to bdi->wb_list in
bdi_init() and never removed. That is different from all other
wb_writeback structures which get added to the list when created and
removed from it before wb_shutdown().
So move list addition of root bdi_writeback to bdi_register() and list
removal of all wb_writeback structures to wb_shutdown(). That way a
wb_writeback structure is on bdi->wb_list if and only if it can handle
writeback and it will make it easier for us to handle shutdown of all
wb_writeback structures in bdi_unregister().
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'mm/backing-dev.c')
-rw-r--r-- | mm/backing-dev.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 03d4ba27c133..e3d56dba4da8 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -345,6 +345,8 @@ out_put_bdi: | |||
345 | return err; | 345 | return err; |
346 | } | 346 | } |
347 | 347 | ||
348 | static void cgwb_remove_from_bdi_list(struct bdi_writeback *wb); | ||
349 | |||
348 | /* | 350 | /* |
349 | * Remove bdi from the global list and shutdown any threads we have running | 351 | * Remove bdi from the global list and shutdown any threads we have running |
350 | */ | 352 | */ |
@@ -358,6 +360,7 @@ static void wb_shutdown(struct bdi_writeback *wb) | |||
358 | } | 360 | } |
359 | spin_unlock_bh(&wb->work_lock); | 361 | spin_unlock_bh(&wb->work_lock); |
360 | 362 | ||
363 | cgwb_remove_from_bdi_list(wb); | ||
361 | /* | 364 | /* |
362 | * Drain work list and shutdown the delayed_work. !WB_registered | 365 | * Drain work list and shutdown the delayed_work. !WB_registered |
363 | * tells wb_workfn() that @wb is dying and its work_list needs to | 366 | * tells wb_workfn() that @wb is dying and its work_list needs to |
@@ -491,10 +494,6 @@ static void cgwb_release_workfn(struct work_struct *work) | |||
491 | release_work); | 494 | release_work); |
492 | struct backing_dev_info *bdi = wb->bdi; | 495 | struct backing_dev_info *bdi = wb->bdi; |
493 | 496 | ||
494 | spin_lock_irq(&cgwb_lock); | ||
495 | list_del_rcu(&wb->bdi_node); | ||
496 | spin_unlock_irq(&cgwb_lock); | ||
497 | |||
498 | wb_shutdown(wb); | 497 | wb_shutdown(wb); |
499 | 498 | ||
500 | css_put(wb->memcg_css); | 499 | css_put(wb->memcg_css); |
@@ -526,6 +525,13 @@ static void cgwb_kill(struct bdi_writeback *wb) | |||
526 | percpu_ref_kill(&wb->refcnt); | 525 | percpu_ref_kill(&wb->refcnt); |
527 | } | 526 | } |
528 | 527 | ||
528 | static void cgwb_remove_from_bdi_list(struct bdi_writeback *wb) | ||
529 | { | ||
530 | spin_lock_irq(&cgwb_lock); | ||
531 | list_del_rcu(&wb->bdi_node); | ||
532 | spin_unlock_irq(&cgwb_lock); | ||
533 | } | ||
534 | |||
529 | static int cgwb_create(struct backing_dev_info *bdi, | 535 | static int cgwb_create(struct backing_dev_info *bdi, |
530 | struct cgroup_subsys_state *memcg_css, gfp_t gfp) | 536 | struct cgroup_subsys_state *memcg_css, gfp_t gfp) |
531 | { | 537 | { |
@@ -766,6 +772,13 @@ static void cgwb_bdi_exit(struct backing_dev_info *bdi) | |||
766 | spin_unlock_irq(&cgwb_lock); | 772 | spin_unlock_irq(&cgwb_lock); |
767 | } | 773 | } |
768 | 774 | ||
775 | static void cgwb_bdi_register(struct backing_dev_info *bdi) | ||
776 | { | ||
777 | spin_lock_irq(&cgwb_lock); | ||
778 | list_add_tail_rcu(&bdi->wb.bdi_node, &bdi->wb_list); | ||
779 | spin_unlock_irq(&cgwb_lock); | ||
780 | } | ||
781 | |||
769 | #else /* CONFIG_CGROUP_WRITEBACK */ | 782 | #else /* CONFIG_CGROUP_WRITEBACK */ |
770 | 783 | ||
771 | static int cgwb_bdi_init(struct backing_dev_info *bdi) | 784 | static int cgwb_bdi_init(struct backing_dev_info *bdi) |
@@ -793,6 +806,16 @@ static void cgwb_bdi_exit(struct backing_dev_info *bdi) | |||
793 | wb_congested_put(bdi->wb_congested); | 806 | wb_congested_put(bdi->wb_congested); |
794 | } | 807 | } |
795 | 808 | ||
809 | static void cgwb_bdi_register(struct backing_dev_info *bdi) | ||
810 | { | ||
811 | list_add_tail_rcu(&bdi->wb.bdi_node, &bdi->wb_list); | ||
812 | } | ||
813 | |||
814 | static void cgwb_remove_from_bdi_list(struct bdi_writeback *wb) | ||
815 | { | ||
816 | list_del_rcu(&wb->bdi_node); | ||
817 | } | ||
818 | |||
796 | #endif /* CONFIG_CGROUP_WRITEBACK */ | 819 | #endif /* CONFIG_CGROUP_WRITEBACK */ |
797 | 820 | ||
798 | int bdi_init(struct backing_dev_info *bdi) | 821 | int bdi_init(struct backing_dev_info *bdi) |
@@ -811,8 +834,6 @@ int bdi_init(struct backing_dev_info *bdi) | |||
811 | 834 | ||
812 | ret = cgwb_bdi_init(bdi); | 835 | ret = cgwb_bdi_init(bdi); |
813 | 836 | ||
814 | list_add_tail_rcu(&bdi->wb.bdi_node, &bdi->wb_list); | ||
815 | |||
816 | return ret; | 837 | return ret; |
817 | } | 838 | } |
818 | EXPORT_SYMBOL(bdi_init); | 839 | EXPORT_SYMBOL(bdi_init); |
@@ -848,6 +869,7 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent, | |||
848 | if (IS_ERR(dev)) | 869 | if (IS_ERR(dev)) |
849 | return PTR_ERR(dev); | 870 | return PTR_ERR(dev); |
850 | 871 | ||
872 | cgwb_bdi_register(bdi); | ||
851 | bdi->dev = dev; | 873 | bdi->dev = dev; |
852 | 874 | ||
853 | bdi_debug_register(bdi, dev_name(dev)); | 875 | bdi_debug_register(bdi, dev_name(dev)); |