summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2019-08-26 12:06:54 -0400
committerJens Axboe <axboe@kernel.dk>2019-08-27 11:22:38 -0400
commited288dc0d4aa29f65bd25b31b5cb866aa5664ff9 (patch)
treefbca2981025e2f6300933da4de6423ee3298b4a0
parent34f8fe501f0624de115d087680c84000b5d9abc9 (diff)
writeback: Separate out wb_get_lookup() from wb_get_create()
Separate out wb_get_lookup() which doesn't try to create one if there isn't already one from wb_get_create(). This will be used by later patches. Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--include/linux/backing-dev.h2
-rw-r--r--mm/backing-dev.c55
2 files changed, 39 insertions, 18 deletions
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 84cdcfbc763f..97967ce06de3 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -230,6 +230,8 @@ static inline int bdi_sched_wait(void *word)
230struct bdi_writeback_congested * 230struct bdi_writeback_congested *
231wb_congested_get_create(struct backing_dev_info *bdi, int blkcg_id, gfp_t gfp); 231wb_congested_get_create(struct backing_dev_info *bdi, int blkcg_id, gfp_t gfp);
232void wb_congested_put(struct bdi_writeback_congested *congested); 232void wb_congested_put(struct bdi_writeback_congested *congested);
233struct bdi_writeback *wb_get_lookup(struct backing_dev_info *bdi,
234 struct cgroup_subsys_state *memcg_css);
233struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi, 235struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi,
234 struct cgroup_subsys_state *memcg_css, 236 struct cgroup_subsys_state *memcg_css,
235 gfp_t gfp); 237 gfp_t gfp);
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 612aa7c5ddbd..d9daa3e422d0 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -618,13 +618,12 @@ out_put:
618} 618}
619 619
620/** 620/**
621 * wb_get_create - get wb for a given memcg, create if necessary 621 * wb_get_lookup - get wb for a given memcg
622 * @bdi: target bdi 622 * @bdi: target bdi
623 * @memcg_css: cgroup_subsys_state of the target memcg (must have positive ref) 623 * @memcg_css: cgroup_subsys_state of the target memcg (must have positive ref)
624 * @gfp: allocation mask to use
625 * 624 *
626 * Try to get the wb for @memcg_css on @bdi. If it doesn't exist, try to 625 * Try to get the wb for @memcg_css on @bdi. The returned wb has its
627 * create one. The returned wb has its refcount incremented. 626 * refcount incremented.
628 * 627 *
629 * This function uses css_get() on @memcg_css and thus expects its refcnt 628 * This function uses css_get() on @memcg_css and thus expects its refcnt
630 * to be positive on invocation. IOW, rcu_read_lock() protection on 629 * to be positive on invocation. IOW, rcu_read_lock() protection on
@@ -641,6 +640,39 @@ out_put:
641 * each lookup. On mismatch, the existing wb is discarded and a new one is 640 * each lookup. On mismatch, the existing wb is discarded and a new one is
642 * created. 641 * created.
643 */ 642 */
643struct bdi_writeback *wb_get_lookup(struct backing_dev_info *bdi,
644 struct cgroup_subsys_state *memcg_css)
645{
646 struct bdi_writeback *wb;
647
648 if (!memcg_css->parent)
649 return &bdi->wb;
650
651 rcu_read_lock();
652 wb = radix_tree_lookup(&bdi->cgwb_tree, memcg_css->id);
653 if (wb) {
654 struct cgroup_subsys_state *blkcg_css;
655
656 /* see whether the blkcg association has changed */
657 blkcg_css = cgroup_get_e_css(memcg_css->cgroup, &io_cgrp_subsys);
658 if (unlikely(wb->blkcg_css != blkcg_css || !wb_tryget(wb)))
659 wb = NULL;
660 css_put(blkcg_css);
661 }
662 rcu_read_unlock();
663
664 return wb;
665}
666
667/**
668 * wb_get_create - get wb for a given memcg, create if necessary
669 * @bdi: target bdi
670 * @memcg_css: cgroup_subsys_state of the target memcg (must have positive ref)
671 * @gfp: allocation mask to use
672 *
673 * Try to get the wb for @memcg_css on @bdi. If it doesn't exist, try to
674 * create one. See wb_get_lookup() for more details.
675 */
644struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi, 676struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi,
645 struct cgroup_subsys_state *memcg_css, 677 struct cgroup_subsys_state *memcg_css,
646 gfp_t gfp) 678 gfp_t gfp)
@@ -653,20 +685,7 @@ struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi,
653 return &bdi->wb; 685 return &bdi->wb;
654 686
655 do { 687 do {
656 rcu_read_lock(); 688 wb = wb_get_lookup(bdi, memcg_css);
657 wb = radix_tree_lookup(&bdi->cgwb_tree, memcg_css->id);
658 if (wb) {
659 struct cgroup_subsys_state *blkcg_css;
660
661 /* see whether the blkcg association has changed */
662 blkcg_css = cgroup_get_e_css(memcg_css->cgroup,
663 &io_cgrp_subsys);
664 if (unlikely(wb->blkcg_css != blkcg_css ||
665 !wb_tryget(wb)))
666 wb = NULL;
667 css_put(blkcg_css);
668 }
669 rcu_read_unlock();
670 } while (!wb && !cgwb_create(bdi, memcg_css, gfp)); 689 } while (!wb && !cgwb_create(bdi, memcg_css, gfp));
671 690
672 return wb; 691 return wb;