linux-next: manual merge of the cgroup tree with the block tree

From: Stephen Rothwell
Date: Wed Mar 07 2012 - 00:05:38 EST


Hi Tejun,

Today's linux-next merge of the cgroup tree got a conflict in
block/blk-cgroup.c between commit 7ee9c5620504 ("blkcg: let blkio_group
point to blkio_cgroup directly") from the block tree and commit
761b3ef50e1c ("cgroup: remove cgroup_subsys argument from callbacks")
from the cgroup tree.

I fixed it up (I hope - see below) and can carry the fix as necessary.
--
Cheers,
Stephen Rothwell sfr@xxxxxxxxxxxxxxxx

diff --cc block/blk-cgroup.c
index ee962f3,1359d63..0000000
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@@ -33,16 -28,10 +33,13 @@@ static LIST_HEAD(all_q_list)
struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT };
EXPORT_SYMBOL_GPL(blkio_root_cgroup);

+static struct blkio_policy_type *blkio_policy[BLKIO_NR_POLICIES];
+
- 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 void blkiocg_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 struct cgroup_subsys_state *blkiocg_create(struct cgroup *);
+ static int blkiocg_can_attach(struct cgroup *, struct cgroup_taskset *);
+ static void blkiocg_attach(struct cgroup *, struct cgroup_taskset *);
++static int blkiocg_pre_destroy(struct cgroup *);
+ static void blkiocg_destroy(struct cgroup *);
static int blkiocg_populate(struct cgroup_subsys *, struct cgroup *);

/* for encoding cft->private value on file */
@@@ -1571,48 -1545,52 +1568,46 @@@ static int blkiocg_populate(struct cgro
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(&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);
}

Attachment: pgp00000.pgp
Description: PGP signature