*/
 struct bdi_writeback_congested {
        unsigned long state;            /* WB_[a]sync_congested flags */
+       atomic_t refcnt;                /* nr of attached wb's and blkg */
 
 #ifdef CONFIG_CGROUP_WRITEBACK
        struct backing_dev_info *bdi;   /* the associated bdi */
-       atomic_t refcnt;                /* nr of attached wb's and blkg */
        int blkcg_id;                   /* ID of the associated blkcg */
        struct rb_node rb_node;         /* on bdi->cgwb_congestion_tree */
 #endif
        atomic_long_t tot_write_bandwidth;
 
        struct bdi_writeback wb;  /* the root writeback info for this bdi */
-       struct bdi_writeback_congested wb_congested; /* its congested state */
 #ifdef CONFIG_CGROUP_WRITEBACK
        struct radix_tree_root cgwb_tree; /* radix tree of active cgroup wbs */
        struct rb_root cgwb_congested_tree; /* their congested states */
        atomic_t usage_cnt; /* counts both cgwbs and cgwb_contested's */
+#else
+       struct bdi_writeback_congested *wb_congested;
 #endif
        wait_queue_head_t wb_waitq;
 
 
 #define INIT_BW                (100 << (20 - PAGE_SHIFT))
 
 static int wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi,
-                  gfp_t gfp)
+                  int blkcg_id, gfp_t gfp)
 {
        int i, err;
 
        INIT_LIST_HEAD(&wb->work_list);
        INIT_DELAYED_WORK(&wb->dwork, wb_workfn);
 
+       wb->congested = wb_congested_get_create(bdi, blkcg_id, gfp);
+       if (!wb->congested)
+               return -ENOMEM;
+
        err = fprop_local_init_percpu(&wb->completions, gfp);
        if (err)
-               return err;
+               goto out_put_cong;
 
        for (i = 0; i < NR_WB_STAT_ITEMS; i++) {
                err = percpu_counter_init(&wb->stat[i], 0, gfp);
-               if (err) {
-                       while (--i)
-                               percpu_counter_destroy(&wb->stat[i]);
-                       fprop_local_destroy_percpu(&wb->completions);
-                       return err;
-               }
+               if (err)
+                       goto out_destroy_stat;
        }
 
        return 0;
+
+out_destroy_stat:
+       while (--i)
+               percpu_counter_destroy(&wb->stat[i]);
+       fprop_local_destroy_percpu(&wb->completions);
+out_put_cong:
+       wb_congested_put(wb->congested);
+       return err;
 }
 
 /*
                percpu_counter_destroy(&wb->stat[i]);
 
        fprop_local_destroy_percpu(&wb->completions);
+       wb_congested_put(wb->congested);
 }
 
 #ifdef CONFIG_CGROUP_WRITEBACK
        struct bdi_writeback_congested *new_congested = NULL, *congested;
        struct rb_node **node, *parent;
        unsigned long flags;
-
-       if (blkcg_id == 1)
-               return &bdi->wb_congested;
 retry:
        spin_lock_irqsave(&cgwb_lock, flags);
 
        struct backing_dev_info *bdi = congested->bdi;
        unsigned long flags;
 
-       if (congested->blkcg_id == 1)
-               return;
-
        local_irq_save(flags);
        if (!atomic_dec_and_lock(&congested->refcnt, &cgwb_lock)) {
                local_irq_restore(flags);
 
        css_put(wb->memcg_css);
        css_put(wb->blkcg_css);
-       wb_congested_put(wb->congested);
 
        fprop_local_destroy_percpu(&wb->memcg_completions);
        percpu_ref_exit(&wb->refcnt);
        if (!wb)
                return -ENOMEM;
 
-       ret = wb_init(wb, bdi, gfp);
+       ret = wb_init(wb, bdi, blkcg_css->id, gfp);
        if (ret)
                goto err_free;
 
        if (ret)
                goto err_ref_exit;
 
-       wb->congested = wb_congested_get_create(bdi, blkcg_css->id, gfp);
-       if (!wb->congested) {
-               ret = -ENOMEM;
-               goto err_fprop_exit;
-       }
-
        wb->memcg_css = memcg_css;
        wb->blkcg_css = blkcg_css;
        INIT_WORK(&wb->release_work, cgwb_release_workfn);
        if (ret) {
                if (ret == -EEXIST)
                        ret = 0;
-               goto err_put_congested;
+               goto err_fprop_exit;
        }
        goto out_put;
 
-err_put_congested:
-       wb_congested_put(wb->congested);
 err_fprop_exit:
        fprop_local_destroy_percpu(&wb->memcg_completions);
 err_ref_exit:
        return wb;
 }
 
-static void cgwb_bdi_init(struct backing_dev_info *bdi)
+static int cgwb_bdi_init(struct backing_dev_info *bdi)
 {
-       bdi->wb.memcg_css = mem_cgroup_root_css;
-       bdi->wb.blkcg_css = blkcg_root_css;
-       bdi->wb_congested.blkcg_id = 1;
+       int ret;
+
        INIT_RADIX_TREE(&bdi->cgwb_tree, GFP_ATOMIC);
        bdi->cgwb_congested_tree = RB_ROOT;
        atomic_set(&bdi->usage_cnt, 1);
+
+       ret = wb_init(&bdi->wb, bdi, 1, GFP_KERNEL);
+       if (!ret) {
+               bdi->wb.memcg_css = mem_cgroup_root_css;
+               bdi->wb.blkcg_css = blkcg_root_css;
+       }
+       return ret;
 }
 
 static void cgwb_bdi_destroy(struct backing_dev_info *bdi)
 
 #else  /* CONFIG_CGROUP_WRITEBACK */
 
-static void cgwb_bdi_init(struct backing_dev_info *bdi) { }
+static int cgwb_bdi_init(struct backing_dev_info *bdi)
+{
+       int err;
+
+       bdi->wb_congested = kzalloc(sizeof(*bdi->wb_congested), GFP_KERNEL);
+       if (!bdi->wb_congested)
+               return -ENOMEM;
+
+       err = wb_init(&bdi->wb, bdi, 1, GFP_KERNEL);
+       if (err) {
+               kfree(bdi->wb_congested);
+               return err;
+       }
+       return 0;
+}
+
 static void cgwb_bdi_destroy(struct backing_dev_info *bdi) { }
 
 #endif /* CONFIG_CGROUP_WRITEBACK */
 
 int bdi_init(struct backing_dev_info *bdi)
 {
-       int err;
-
        bdi->dev = NULL;
 
        bdi->min_ratio = 0;
        INIT_LIST_HEAD(&bdi->bdi_list);
        init_waitqueue_head(&bdi->wb_waitq);
 
-       err = wb_init(&bdi->wb, bdi, GFP_KERNEL);
-       if (err)
-               return err;
-
-       bdi->wb_congested.state = 0;
-       bdi->wb.congested = &bdi->wb_congested;
-
-       cgwb_bdi_init(bdi);
-       return 0;
+       return cgwb_bdi_init(bdi);
 }
 EXPORT_SYMBOL(bdi_init);