aboutsummaryrefslogtreecommitdiffstats
path: root/mm/backing-dev.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2017-03-22 20:36:56 -0400
committerJens Axboe <axboe@fb.com>2017-03-22 22:11:27 -0400
commite8cb72b322cf4a729633b7e2080fbeab477f6ea2 (patch)
tree1bf1accf057f327631748d40be3fd4b0877b5515 /mm/backing-dev.c
parent810df54a64fb7841d6511f67818f3e1589c249a2 (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.c34
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
348static 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
528static 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
529static int cgwb_create(struct backing_dev_info *bdi, 535static 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
775static 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
771static int cgwb_bdi_init(struct backing_dev_info *bdi) 784static 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
809static void cgwb_bdi_register(struct backing_dev_info *bdi)
810{
811 list_add_tail_rcu(&bdi->wb.bdi_node, &bdi->wb_list);
812}
813
814static 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
798int bdi_init(struct backing_dev_info *bdi) 821int 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}
818EXPORT_SYMBOL(bdi_init); 839EXPORT_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));