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.
Unified · Split
| @@ -230,6 +230,8 @@ static inline int bdi_sched_wait(void *word) · 229 unmodified lines | ||
| 230 | 230 | struct bdi_writeback_congested * |
| 231 | 231 | wb_congested_get_create(struct backing_dev_info *bdi, int blkcg_id, gfp_t gfp); |
| 232 | 232 | void wb_congested_put(struct bdi_writeback_congested *congested); |
| 233 | +struct bdi_writeback *wb_get_lookup(struct backing_dev_info *bdi, | |
| 234 | + struct cgroup_subsys_state *memcg_css); | |
| 233 | 235 | struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi, |
| 234 | 236 | struct cgroup_subsys_state *memcg_css, |
| 235 | 237 | gfp_t gfp); |
| @@ -618,13 +618,12 @@ out_put: · 617 unmodified lines | ||
| 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 | 622 | * @bdi: target bdi |
| 623 | 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 | |
| 627 | − * create one. The returned wb has its refcount incremented. | |
| 625 | + * Try to get the wb for @memcg_css on @bdi. The returned wb has its | |
| 626 | + * refcount incremented. | |
| 628 | 627 | * |
| 629 | 628 | * This function uses css_get() on @memcg_css and thus expects its refcnt |
| 630 | 629 | * to be positive on invocation. IOW, rcu_read_lock() protection on |
| @@ -641,6 +640,39 @@ out_put: · 10 unmodified lines | ||
| 641 | 640 | * each lookup. On mismatch, the existing wb is discarded and a new one is |
| 642 | 641 | * created. |
| 643 | 642 | */ |
| 643 | +struct 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 | + */ | |
| 644 | 676 | struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi, |
| 645 | 677 | struct cgroup_subsys_state *memcg_css, |
| 646 | 678 | gfp_t gfp) |
| @@ -653,20 +685,7 @@ struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi, · 6 unmodified lines | ||
| 653 | 685 | return &bdi->wb; |
| 654 | 686 | |
| 655 | 687 | do { |
| 656 | − rcu_read_lock(); | |
| 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(); | |
| 688 | + wb = wb_get_lookup(bdi, memcg_css); | |
| 670 | 689 | } while (!wb && !cgwb_create(bdi, memcg_css, gfp)); |
| 671 | 690 | |
| 672 | 691 | return wb; |