struct blkcg_gq *parent;
/* reference count */
- atomic_t refcnt;
+ struct percpu_ref refcnt;
/* is this blkg online? protected by both blkcg and q locks */
bool online;
return task_css(current, io_cgrp_id);
}
-/**
- * blkcg_get_css - find and get a reference to the css
- *
- * Find the css associated with either the kthread or the current task.
- * This takes a reference on the blkcg which will need to be managed by the
- * caller.
- */
-static inline struct cgroup_subsys_state *blkcg_get_css(void)
-{
- struct cgroup_subsys_state *css;
-
- rcu_read_lock();
-
- css = kthread_blkcg();
- if (css) {
- css_get(css);
- } else {
- /*
- * This is a bit complicated. It is possible task_css() is
- * seeing an old css pointer here. This is caused by the
- * current thread migrating away from this cgroup and this
- * cgroup dying. css_tryget() will fail when trying to take a
- * ref on a cgroup that's ref count has hit 0.
- *
- * Therefore, if it does fail, this means current must have
- * been swapped away already and this is waiting for it to
- * propagate on the polling cpu. Hence the use of cpu_relax().
- */
- while (true) {
- css = task_css(current, io_cgrp_id);
- if (likely(css_tryget(css)))
- break;
- cpu_relax();
- }
- }
-
- rcu_read_unlock();
-
- return css;
-}
-
static inline struct blkcg *css_to_blkcg(struct cgroup_subsys_state *css)
{
return css ? container_of(css, struct blkcg, css) : NULL;
*/
static inline struct blkcg *__bio_blkcg(struct bio *bio)
{
- if (bio && bio->bi_css)
- return css_to_blkcg(bio->bi_css);
+ if (bio && bio->bi_blkg)
+ return bio->bi_blkg->blkcg;
return css_to_blkcg(blkcg_css());
}
*/
static inline struct blkcg *bio_blkcg(struct bio *bio)
{
- if (bio && bio->bi_css)
- return css_to_blkcg(bio->bi_css);
+ if (bio && bio->bi_blkg)
+ return bio->bi_blkg->blkcg;
return NULL;
}
*/
static inline void blkg_get(struct blkcg_gq *blkg)
{
- WARN_ON_ONCE(atomic_read(&blkg->refcnt) <= 0);
- atomic_inc(&blkg->refcnt);
+ percpu_ref_get(&blkg->refcnt);
}
/**
*/
static inline struct blkcg_gq *blkg_try_get(struct blkcg_gq *blkg)
{
- if (atomic_inc_not_zero(&blkg->refcnt))
+ if (percpu_ref_tryget(&blkg->refcnt))
return blkg;
return NULL;
}
*/
static inline struct blkcg_gq *blkg_try_get_closest(struct blkcg_gq *blkg)
{
- while (!atomic_inc_not_zero(&blkg->refcnt))
+ while (!percpu_ref_tryget(&blkg->refcnt))
blkg = blkg->parent;
return blkg;
}
-void __blkg_release_rcu(struct rcu_head *rcu);
-
/**
* blkg_put - put a blkg reference
* @blkg: blkg to put
*/
static inline void blkg_put(struct blkcg_gq *blkg)
{
- WARN_ON_ONCE(atomic_read(&blkg->refcnt) <= 0);
- if (atomic_dec_and_test(&blkg->refcnt))
- call_rcu(&blkg->rcu_head, __blkg_release_rcu);
+ percpu_ref_put(&blkg->refcnt);
}
/**