writeback: Separate out wb_get_lookup() from wb_get_create()
authorTejun Heo <tj@kernel.org>
Mon, 26 Aug 2019 16:06:54 +0000 (09:06 -0700)
committerJens Axboe <axboe@kernel.dk>
Tue, 27 Aug 2019 15:22:38 +0000 (09:22 -0600)
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>
include/linux/backing-dev.h
mm/backing-dev.c

index 84cdcfb..97967ce 100644 (file)
@@ -230,6 +230,8 @@ static inline int bdi_sched_wait(void *word)
 struct bdi_writeback_congested *
 wb_congested_get_create(struct backing_dev_info *bdi, int blkcg_id, gfp_t gfp);
 void wb_congested_put(struct bdi_writeback_congested *congested);
+struct bdi_writeback *wb_get_lookup(struct backing_dev_info *bdi,
+                                   struct cgroup_subsys_state *memcg_css);
 struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi,
                                    struct cgroup_subsys_state *memcg_css,
                                    gfp_t gfp);
index 612aa7c..d9daa3e 100644 (file)
@@ -618,13 +618,12 @@ out_put:
 }
 
 /**
- * wb_get_create - get wb for a given memcg, create if necessary
+ * wb_get_lookup - get wb for a given memcg
  * @bdi: target bdi
  * @memcg_css: cgroup_subsys_state of the target memcg (must have positive ref)
- * @gfp: allocation mask to use
  *
- * Try to get the wb for @memcg_css on @bdi.  If it doesn't exist, try to
- * create one.  The returned wb has its refcount incremented.
+ * Try to get the wb for @memcg_css on @bdi.  The returned wb has its
+ * refcount incremented.
  *
  * This function uses css_get() on @memcg_css and thus expects its refcnt
  * to be positive on invocation.  IOW, rcu_read_lock() protection on
@@ -641,6 +640,39 @@ out_put:
  * each lookup.  On mismatch, the existing wb is discarded and a new one is
  * created.
  */
+struct bdi_writeback *wb_get_lookup(struct backing_dev_info *bdi,
+                                   struct cgroup_subsys_state *memcg_css)
+{
+       struct bdi_writeback *wb;
+
+       if (!memcg_css->parent)
+               return &bdi->wb;
+
+       rcu_read_lock();
+       wb = radix_tree_lookup(&bdi->cgwb_tree, memcg_css->id);
+       if (wb) {
+               struct cgroup_subsys_state *blkcg_css;
+
+               /* see whether the blkcg association has changed */
+               blkcg_css = cgroup_get_e_css(memcg_css->cgroup, &io_cgrp_subsys);
+               if (unlikely(wb->blkcg_css != blkcg_css || !wb_tryget(wb)))
+                       wb = NULL;
+               css_put(blkcg_css);
+       }
+       rcu_read_unlock();
+
+       return wb;
+}
+
+/**
+ * wb_get_create - get wb for a given memcg, create if necessary
+ * @bdi: target bdi
+ * @memcg_css: cgroup_subsys_state of the target memcg (must have positive ref)
+ * @gfp: allocation mask to use
+ *
+ * Try to get the wb for @memcg_css on @bdi.  If it doesn't exist, try to
+ * create one.  See wb_get_lookup() for more details.
+ */
 struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi,
                                    struct cgroup_subsys_state *memcg_css,
                                    gfp_t gfp)
@@ -653,20 +685,7 @@ struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi,
                return &bdi->wb;
 
        do {
-               rcu_read_lock();
-               wb = radix_tree_lookup(&bdi->cgwb_tree, memcg_css->id);
-               if (wb) {
-                       struct cgroup_subsys_state *blkcg_css;
-
-                       /* see whether the blkcg association has changed */
-                       blkcg_css = cgroup_get_e_css(memcg_css->cgroup,
-                                                    &io_cgrp_subsys);
-                       if (unlikely(wb->blkcg_css != blkcg_css ||
-                                    !wb_tryget(wb)))
-                               wb = NULL;
-                       css_put(blkcg_css);
-               }
-               rcu_read_unlock();
+               wb = wb_get_lookup(bdi, memcg_css);
        } while (!wb && !cgwb_create(bdi, memcg_css, gfp));
 
        return wb;