blkcg: change blkg reference counting to use percpu_ref
[sfrench/cifs-2.6.git] / include / linux / blk-cgroup.h
index 8b069c3775eeb67ed27be086eb7277545bd3b061..d19ef15a673d8dbc30aada8cde759574540ab396 100644 (file)
@@ -124,7 +124,7 @@ struct blkcg_gq {
        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;
@@ -247,47 +247,6 @@ static inline struct cgroup_subsys_state *blkcg_css(void)
        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;
@@ -309,8 +268,8 @@ static inline struct blkcg *css_to_blkcg(struct cgroup_subsys_state *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 css_to_blkcg(blkcg_css());
 }
 
@@ -324,8 +283,8 @@ static inline struct blkcg *__bio_blkcg(struct bio *bio)
  */
 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;
 }
 
@@ -528,8 +487,7 @@ static inline int blkg_path(struct blkcg_gq *blkg, char *buf, int buflen)
  */
 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);
 }
 
 /**
@@ -541,7 +499,7 @@ static inline void blkg_get(struct blkcg_gq *blkg)
  */
 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;
 }
@@ -555,23 +513,19 @@ static inline struct blkcg_gq *blkg_try_get(struct blkcg_gq *blkg)
  */
 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);
 }
 
 /**