The independent functions of alloc and free will be used while changing
the number of writeback contexts.

Signed-off-by: Kundan Kumar <[email protected]>
Signed-off-by: Anuj Gupta <[email protected]>
---
 mm/backing-dev.c | 72 ++++++++++++++++++++++++++++++++----------------
 1 file changed, 49 insertions(+), 23 deletions(-)

diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 0a3204a3a3a3..2a8f3b683b2d 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -1038,8 +1038,46 @@ static void cgwb_remove_from_bdi_list(struct 
bdi_writeback *wb)
 
 #endif /* CONFIG_CGROUP_WRITEBACK */
 
+static struct bdi_writeback_ctx **wb_ctx_alloc(struct backing_dev_info *bdi,
+                                              int num_ctxs)
+{
+       struct bdi_writeback_ctx **wb_ctx;
+
+       wb_ctx = kcalloc(num_ctxs, sizeof(struct bdi_writeback_ctx *),
+                            GFP_KERNEL);
+       if (!wb_ctx)
+               return NULL;
+
+       for (int i = 0; i < num_ctxs; i++) {
+               wb_ctx[i] = (struct bdi_writeback_ctx *)
+                       kzalloc(sizeof(struct bdi_writeback_ctx), GFP_KERNEL);
+               if (!wb_ctx[i]) {
+                       pr_err("Failed to allocate %d", i);
+                       while (--i >= 0)
+                               kfree(wb_ctx[i]);
+                       kfree(wb_ctx);
+                       return NULL;
+               }
+               INIT_LIST_HEAD(&wb_ctx[i]->wb_list);
+               init_waitqueue_head(&wb_ctx[i]->wb_waitq);
+       }
+       return wb_ctx;
+}
+
+static void wb_ctx_free(struct backing_dev_info *bdi)
+{
+       struct bdi_writeback_ctx *bdi_wb_ctx;
+
+       for_each_bdi_wb_ctx(bdi, bdi_wb_ctx) {
+               kfree(bdi_wb_ctx);
+       }
+       kfree(bdi->wb_ctx);
+}
+
 int bdi_init(struct backing_dev_info *bdi)
 {
+       int ret;
+
        bdi->dev = NULL;
 
        kref_init(&bdi->refcnt);
@@ -1047,48 +1085,36 @@ int bdi_init(struct backing_dev_info *bdi)
        bdi->max_ratio = 100 * BDI_RATIO_SCALE;
        bdi->max_prop_frac = FPROP_FRAC_BASE;
 
+       INIT_LIST_HEAD(&bdi->bdi_list);
+
        /*
         * User can configure nr_wb_ctx using the newly introduced sysfs knob.
         * echo N > /sys/class/bdi/<maj>:<min>/nwritebacks
         * Filesystem can also increase same during mount.
         */
        bdi->nr_wb_ctx = 1;
-       bdi->wb_ctx = kcalloc(bdi->nr_wb_ctx,
-                                 sizeof(struct bdi_writeback_ctx *),
-                                 GFP_KERNEL);
-       INIT_LIST_HEAD(&bdi->bdi_list);
-       for (int i = 0; i < bdi->nr_wb_ctx; i++) {
-               bdi->wb_ctx[i] = (struct bdi_writeback_ctx *)
-                        kzalloc(sizeof(struct bdi_writeback_ctx), GFP_KERNEL);
-               if (!bdi->wb_ctx[i]) {
-                       pr_err("Failed to allocate %d", i);
-                       while (--i >= 0)
-                               kfree(bdi->wb_ctx[i]);
-                       kfree(bdi->wb_ctx);
-                       return -ENOMEM;
-               }
-               INIT_LIST_HEAD(&bdi->wb_ctx[i]->wb_list);
-               init_waitqueue_head(&bdi->wb_ctx[i]->wb_waitq);
-       }
+
+       bdi->wb_ctx = wb_ctx_alloc(bdi, bdi->nr_wb_ctx);
+       if (!bdi->wb_ctx)
+               return -ENOMEM;
+
        bdi->last_bdp_sleep = jiffies;
 
-       return cgwb_bdi_init(bdi);
+       ret = cgwb_bdi_init(bdi);
+       if (ret)
+               wb_ctx_free(bdi);
+       return ret;
 }
 
 struct backing_dev_info *bdi_alloc(int node_id)
 {
        struct backing_dev_info *bdi;
-       struct bdi_writeback_ctx *bdi_wb_ctx;
 
        bdi = kzalloc_node(sizeof(*bdi), GFP_KERNEL, node_id);
        if (!bdi)
                return NULL;
 
        if (bdi_init(bdi)) {
-               for_each_bdi_wb_ctx(bdi, bdi_wb_ctx) {
-                       kfree(bdi_wb_ctx);
-               }
-               kfree(bdi->wb_ctx);
                kfree(bdi);
                return NULL;
        }
-- 
2.25.1



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to