Merge branch 'for-3.5' of ../cgroup into block/for-3.5/core-merged
authorTejun Heo <tj@kernel.org>
Sun, 1 Apr 2012 19:30:01 +0000 (12:30 -0700)
committerTejun Heo <tj@kernel.org>
Sun, 1 Apr 2012 19:55:00 +0000 (12:55 -0700)
cgroup/for-3.5 contains the following changes which blk-cgroup needs
to proceed with the on-going cleanup.

* Dynamic addition and removal of cftypes to make config/stat file
  handling modular for policies.

* cgroup removal update to not wait for css references to drain to fix
  blkcg removal hang caused by cfq caching cfqgs.

Pull in cgroup/for-3.5 into block/for-3.5/core.  This causes the
following conflicts in block/blk-cgroup.c.

761b3ef50e "cgroup: remove cgroup_subsys argument from callbacks"
  conflicts with blkiocg_pre_destroy() addition and blkiocg_attach()
  removal.  Resolved by removing @subsys from all subsys methods.

676f7c8f84 "cgroup: relocate cftype and cgroup_subsys definitions in
  controllers" conflicts with ->pre_destroy() and ->attach() updates
  and removal of modular config.  Resolved by dropping forward
  declarations of the methods and applying updates to the relocated
  blkio_subsys.

4baf6e3325 "cgroup: convert all non-memcg controllers to the new
  cftype interface" builds upon the previous item.  Resolved by adding
  ->base_cftypes to the relocated blkio_subsys.

Signed-off-by: Tejun Heo <tj@kernel.org>
1  2 
block/blk-cgroup.c
block/blk-ioc.c
block/blk.h
fs/bio.c
include/linux/bio.h
init/Kconfig
kernel/fork.c

index aa54c4110f5414ecfe3bf8e884cfc813b73376bf,126c341955de162cba789040d0908b1d147c943c..4fdeb46b44361d33d8a9d2087c6887d66290edce
@@@ -41,34 -28,60 +41,14 @@@ static DECLARE_DELAYED_WORK(blkio_stat_
  struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT };
  EXPORT_SYMBOL_GPL(blkio_root_cgroup);
  
- static struct cgroup_subsys_state *blkiocg_create(struct cgroup_subsys *,
-                                                 struct cgroup *);
- static int blkiocg_can_attach(struct cgroup_subsys *, struct cgroup *,
-                             struct cgroup_taskset *);
- static int blkiocg_pre_destroy(struct cgroup_subsys *, struct cgroup *);
- static void blkiocg_destroy(struct cgroup_subsys *, struct cgroup *);
- static int blkiocg_populate(struct cgroup_subsys *, struct cgroup *);
 +static struct blkio_policy_type *blkio_policy[BLKIO_NR_POLICIES];
 +
  /* for encoding cft->private value on file */
  #define BLKIOFILE_PRIVATE(x, val)     (((x) << 16) | (val))
  /* What policy owns the file, proportional or throttle */
  #define BLKIOFILE_POLICY(val)         (((val) >> 16) & 0xffff)
  #define BLKIOFILE_ATTR(val)           ((val) & 0xffff)
  
- struct cgroup_subsys blkio_subsys = {
-       .name = "blkio",
-       .create = blkiocg_create,
-       .can_attach = blkiocg_can_attach,
-       .pre_destroy = blkiocg_pre_destroy,
-       .destroy = blkiocg_destroy,
-       .populate = blkiocg_populate,
-       .subsys_id = blkio_subsys_id,
-       .module = THIS_MODULE,
- };
- EXPORT_SYMBOL_GPL(blkio_subsys);
 -static inline void blkio_policy_insert_node(struct blkio_cgroup *blkcg,
 -                                          struct blkio_policy_node *pn)
 -{
 -      list_add(&pn->node, &blkcg->policy_list);
 -}
 -
 -static inline bool cftype_blkg_same_policy(struct cftype *cft,
 -                      struct blkio_group *blkg)
 -{
 -      enum blkio_policy_id plid = BLKIOFILE_POLICY(cft->private);
 -
 -      if (blkg->plid == plid)
 -              return 1;
 -
 -      return 0;
 -}
 -
 -/* Determines if policy node matches cgroup file being accessed */
 -static inline bool pn_matches_cftype(struct cftype *cft,
 -                      struct blkio_policy_node *pn)
 -{
 -      enum blkio_policy_id plid = BLKIOFILE_POLICY(cft->private);
 -      int fileid = BLKIOFILE_ATTR(cft->private);
 -
 -      return (plid == pn->plid && fileid == pn->fileid);
 -}
 -
 -/* Must be called with blkcg->lock held */
 -static inline void blkio_policy_delete_node(struct blkio_policy_node *pn)
 -{
 -      list_del(&pn->node);
 -}
 -
 -/* Must be called with blkcg->lock held */
 -static struct blkio_policy_node *
 -blkio_policy_search_node(const struct blkio_cgroup *blkcg, dev_t dev,
 -              enum blkio_policy_id plid, int fileid)
 -{
 -      struct blkio_policy_node *pn;
 -
 -      list_for_each_entry(pn, &blkcg->policy_list, node) {
 -              if (pn->dev == dev && pn->plid == plid && pn->fileid == fileid)
 -                      return pn;
 -      }
 -
 -      return NULL;
 -}
--
  struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup)
  {
        return container_of(cgroup_subsys_state(cgroup, blkio_subsys_id),
@@@ -1563,64 -1515,61 +1543,56 @@@ struct cftype blkio_files[] = 
                .read_map = blkiocg_file_read_map,
        },
  #endif
+       { }     /* terminate */
  };
  
- static int blkiocg_populate(struct cgroup_subsys *subsys, struct cgroup *cgroup)
- {
-       return cgroup_add_files(cgroup, subsys, blkio_files,
-                               ARRAY_SIZE(blkio_files));
- }
 -static void blkiocg_destroy(struct cgroup *cgroup)
 +/**
 + * blkiocg_pre_destroy - cgroup pre_destroy callback
-  * @subsys: cgroup subsys
 + * @cgroup: cgroup of interest
 + *
 + * This function is called when @cgroup is about to go away and responsible
 + * for shooting down all blkgs associated with @cgroup.  blkgs should be
 + * removed while holding both q and blkcg locks.  As blkcg lock is nested
 + * inside q lock, this function performs reverse double lock dancing.
 + *
 + * This is the blkcg counterpart of ioc_release_fn().
 + */
- static int blkiocg_pre_destroy(struct cgroup_subsys *subsys,
-                              struct cgroup *cgroup)
++static int blkiocg_pre_destroy(struct cgroup *cgroup)
  {
        struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup);
 -      unsigned long flags;
 -      struct blkio_group *blkg;
 -      void *key;
 -      struct blkio_policy_type *blkiop;
 -      struct blkio_policy_node *pn, *pntmp;
  
 -      rcu_read_lock();
 -      do {
 -              spin_lock_irqsave(&blkcg->lock, flags);
 +      spin_lock_irq(&blkcg->lock);
  
 -              if (hlist_empty(&blkcg->blkg_list)) {
 -                      spin_unlock_irqrestore(&blkcg->lock, flags);
 -                      break;
 +      while (!hlist_empty(&blkcg->blkg_list)) {
 +              struct blkio_group *blkg = hlist_entry(blkcg->blkg_list.first,
 +                                              struct blkio_group, blkcg_node);
 +              struct request_queue *q = blkg->q;
 +
 +              if (spin_trylock(q->queue_lock)) {
 +                      blkg_destroy(blkg);
 +                      spin_unlock(q->queue_lock);
 +              } else {
 +                      spin_unlock_irq(&blkcg->lock);
 +                      cpu_relax();
 +                      spin_lock_irq(&blkcg->lock);
                }
 +      }
  
 -              blkg = hlist_entry(blkcg->blkg_list.first, struct blkio_group,
 -                                      blkcg_node);
 -              key = rcu_dereference(blkg->key);
 -              __blkiocg_del_blkio_group(blkg);
 -
 -              spin_unlock_irqrestore(&blkcg->lock, flags);
 -
 -              /*
 -               * This blkio_group is being unlinked as associated cgroup is
 -               * going away. Let all the IO controlling policies know about
 -               * this event.
 -               */
 -              spin_lock(&blkio_list_lock);
 -              list_for_each_entry(blkiop, &blkio_list, list) {
 -                      if (blkiop->plid != blkg->plid)
 -                              continue;
 -                      blkiop->ops.blkio_unlink_group_fn(key, blkg);
 -              }
 -              spin_unlock(&blkio_list_lock);
 -      } while (1);
 +      spin_unlock_irq(&blkcg->lock);
 +      return 0;
 +}
  
- static void blkiocg_destroy(struct cgroup_subsys *subsys, struct cgroup *cgroup)
 -      list_for_each_entry_safe(pn, pntmp, &blkcg->policy_list, node) {
 -              blkio_policy_delete_node(pn);
 -              kfree(pn);
 -      }
++static void blkiocg_destroy(struct cgroup *cgroup)
 +{
 +      struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup);
  
 -      free_css_id(&blkio_subsys, &blkcg->css);
 -      rcu_read_unlock();
        if (blkcg != &blkio_root_cgroup)
                kfree(blkcg);
  }
  
- static struct cgroup_subsys_state *
- blkiocg_create(struct cgroup_subsys *subsys, struct cgroup *cgroup)
+ static struct cgroup_subsys_state *blkiocg_create(struct cgroup *cgroup)
  {
 +      static atomic64_t id_seq = ATOMIC64_INIT(0);
        struct blkio_cgroup *blkcg;
        struct cgroup *parent = cgroup->parent;
  
@@@ -1739,32 -1631,27 +1710,44 @@@ static void blkcg_bypass_start(void
        }
  }
  
 -      .attach = blkiocg_attach,
 +static void blkcg_bypass_end(void)
 +      __releases(&all_q_mutex)
 +{
 +      struct request_queue *q;
 +
 +      list_for_each_entry(q, &all_q_list, all_q_node)
 +              blk_queue_bypass_end(q);
 +
 +      mutex_unlock(&all_q_mutex);
 +}
 +
+ struct cgroup_subsys blkio_subsys = {
+       .name = "blkio",
+       .create = blkiocg_create,
+       .can_attach = blkiocg_can_attach,
 -#ifdef CONFIG_BLK_CGROUP
 -      /* note: blkio_subsys_id is otherwise defined in blk-cgroup.h */
++      .pre_destroy = blkiocg_pre_destroy,
+       .destroy = blkiocg_destroy,
 -#endif
+       .subsys_id = blkio_subsys_id,
 -      .use_id = 1,
+       .base_cftypes = blkio_files,
+       .module = THIS_MODULE,
+ };
+ EXPORT_SYMBOL_GPL(blkio_subsys);
  void blkio_policy_register(struct blkio_policy_type *blkiop)
  {
 +      struct request_queue *q;
 +
 +      blkcg_bypass_start();
        spin_lock(&blkio_list_lock);
 +
 +      BUG_ON(blkio_policy[blkiop->plid]);
 +      blkio_policy[blkiop->plid] = blkiop;
        list_add_tail(&blkiop->list, &blkio_list);
 +
        spin_unlock(&blkio_list_lock);
 +      list_for_each_entry(q, &all_q_list, all_q_node)
 +              update_root_blkg_pd(q, blkiop->plid);
 +      blkcg_bypass_end();
  }
  EXPORT_SYMBOL_GPL(blkio_policy_register);
  
diff --cc block/blk-ioc.c
Simple merge
diff --cc block/blk.h
Simple merge
diff --cc fs/bio.c
index 142214b80039f5d216f6b5c55329056e62c6bade,e453924036e96dac3583854cfd45e40699567cfb..4ef7bd4cd48fcb1ba805fc3b7eca638ee8f69182
+++ b/fs/bio.c
  #include <linux/slab.h>
  #include <linux/init.h>
  #include <linux/kernel.h>
- #include <linux/module.h>
+ #include <linux/export.h>
  #include <linux/mempool.h>
  #include <linux/workqueue.h>
 +#include <linux/cgroup.h>
  #include <scsi/sg.h>          /* for struct sg_iovec */
  
  #include <trace/events/block.h>
Simple merge
diff --cc init/Kconfig
Simple merge
diff --cc kernel/fork.c
Simple merge