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 | struct bdi_writeback_congested * | 230 | struct bdi_writeback_congested * |
| 231 | wb_congested_get_create(struct backing_dev_info *bdi, int blkcg_id, gfp_t gfp); | 231 | wb_congested_get_create(struct backing_dev_info *bdi, int blkcg_id, gfp_t gfp); |
| 232 | void wb_congested_put(struct bdi_writeback_congested *congested); | 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 | struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi, | 235 | struct 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); |
| @@ -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 | * @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: · 10 unmodified lines | |||
| 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 | */ |
| 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 | struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi, | 676 | struct 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, · 6 unmodified lines | |||
| 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; |