Skip to content

Commit

Permalink
blkcg: rename blkcg->cgwb_refcnt to ->online_pin and always use it
Browse files Browse the repository at this point in the history
blkcg->cgwb_refcnt is used to delay blkcg offlining so that blkgs
don't get offlined while there are active cgwbs on them.  However, it
ends up making offlining unordered sometimes causing parents to be
offlined before children.

To fix it, we want child blkcgs to pin the parents' online states
turning the refcnt into a more generic online pinning mechanism.

In prepartion,

* blkcg->cgwb_refcnt -> blkcg->online_pin
* blkcg_cgwb_get/put() -> blkcg_pin/unpin_online()
* Take them out of CONFIG_CGROUP_WRITEBACK

Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
htejun authored and axboe committed Apr 1, 2020
1 parent 1a323ea commit d866dbf
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 32 deletions.
6 changes: 3 additions & 3 deletions block/blk-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -883,8 +883,8 @@ static void blkcg_css_offline(struct cgroup_subsys_state *css)
/* this prevents anyone from attaching or migrating to this blkcg */
wb_blkcg_offline(blkcg);

/* put the base cgwb reference allowing step 2 to be triggered */
blkcg_cgwb_put(blkcg);
/* put the base online pin allowing step 2 to be triggered */
blkcg_unpin_online(blkcg);
}

/**
Expand Down Expand Up @@ -983,11 +983,11 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css)
}

spin_lock_init(&blkcg->lock);
refcount_set(&blkcg->online_pin, 1);
INIT_RADIX_TREE(&blkcg->blkg_tree, GFP_NOWAIT | __GFP_NOWARN);
INIT_HLIST_HEAD(&blkcg->blkg_list);
#ifdef CONFIG_CGROUP_WRITEBACK
INIT_LIST_HEAD(&blkcg->cgwb_list);
refcount_set(&blkcg->cgwb_refcnt, 1);
#endif
list_add_tail(&blkcg->all_blkcgs_node, &all_blkcgs);

Expand Down
39 changes: 13 additions & 26 deletions include/linux/blk-cgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct blkcg_gq;
struct blkcg {
struct cgroup_subsys_state css;
spinlock_t lock;
refcount_t online_pin;

struct radix_tree_root blkg_tree;
struct blkcg_gq __rcu *blkg_hint;
Expand All @@ -56,7 +57,6 @@ struct blkcg {
struct list_head all_blkcgs_node;
#ifdef CONFIG_CGROUP_WRITEBACK
struct list_head cgwb_list;
refcount_t cgwb_refcnt;
#endif
};

Expand Down Expand Up @@ -412,47 +412,34 @@ static inline struct blkcg *cpd_to_blkcg(struct blkcg_policy_data *cpd)

extern void blkcg_destroy_blkgs(struct blkcg *blkcg);

#ifdef CONFIG_CGROUP_WRITEBACK

/**
* blkcg_cgwb_get - get a reference for blkcg->cgwb_list
* blkcg_pin_online - pin online state
* @blkcg: blkcg of interest
*
* This is used to track the number of active wb's related to a blkcg.
* While pinned, a blkcg is kept online. This is primarily used to
* impedance-match blkg and cgwb lifetimes so that blkg doesn't go offline
* while an associated cgwb is still active.
*/
static inline void blkcg_cgwb_get(struct blkcg *blkcg)
static inline void blkcg_pin_online(struct blkcg *blkcg)
{
refcount_inc(&blkcg->cgwb_refcnt);
refcount_inc(&blkcg->online_pin);
}

/**
* blkcg_cgwb_put - put a reference for @blkcg->cgwb_list
* blkcg_unpin_online - unpin online state
* @blkcg: blkcg of interest
*
* This is used to track the number of active wb's related to a blkcg.
* When this count goes to zero, all active wb has finished so the
* This is primarily used to impedance-match blkg and cgwb lifetimes so
* that blkg doesn't go offline while an associated cgwb is still active.
* When this count goes to zero, all active cgwbs have finished so the
* blkcg can continue destruction by calling blkcg_destroy_blkgs().
* This work may occur in cgwb_release_workfn() on the cgwb_release
* workqueue.
*/
static inline void blkcg_cgwb_put(struct blkcg *blkcg)
static inline void blkcg_unpin_online(struct blkcg *blkcg)
{
if (refcount_dec_and_test(&blkcg->cgwb_refcnt))
if (refcount_dec_and_test(&blkcg->online_pin))
blkcg_destroy_blkgs(blkcg);
}

#else

static inline void blkcg_cgwb_get(struct blkcg *blkcg) { }

static inline void blkcg_cgwb_put(struct blkcg *blkcg)
{
/* wb isn't being accounted, so trigger destruction right away */
blkcg_destroy_blkgs(blkcg);
}

#endif

/**
* blkg_path - format cgroup path of blkg
* @blkg: blkg of interest
Expand Down
6 changes: 3 additions & 3 deletions mm/backing-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,8 +491,8 @@ static void cgwb_release_workfn(struct work_struct *work)
css_put(wb->blkcg_css);
mutex_unlock(&wb->bdi->cgwb_release_mutex);

/* triggers blkg destruction if cgwb_refcnt becomes zero */
blkcg_cgwb_put(blkcg);
/* triggers blkg destruction if no online users left */
blkcg_unpin_online(blkcg);

fprop_local_destroy_percpu(&wb->memcg_completions);
percpu_ref_exit(&wb->refcnt);
Expand Down Expand Up @@ -592,7 +592,7 @@ static int cgwb_create(struct backing_dev_info *bdi,
list_add_tail_rcu(&wb->bdi_node, &bdi->wb_list);
list_add(&wb->memcg_node, memcg_cgwb_list);
list_add(&wb->blkcg_node, blkcg_cgwb_list);
blkcg_cgwb_get(blkcg);
blkcg_pin_online(blkcg);
css_get(memcg_css);
css_get(blkcg_css);
}
Expand Down

0 comments on commit d866dbf

Please sign in to comment.