aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup_freezer.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-08-08 20:11:23 -0400
committerTejun Heo <tj@kernel.org>2013-08-08 20:11:23 -0400
commiteb95419b023abacb415e2a18fea899023ce7624d (patch)
tree705284469b67cbe440b86c6cb81e1cf27648eba9 /kernel/cgroup_freezer.c
parent6387698699afd72d6304566fb6ccf84bffe07c56 (diff)
cgroup: pass around cgroup_subsys_state instead of cgroup in subsystem methods
cgroup is currently in the process of transitioning to using struct cgroup_subsys_state * as the primary handle instead of struct cgroup * in subsystem implementations for the following reasons. * With unified hierarchy, subsystems will be dynamically bound and unbound from cgroups and thus css's (cgroup_subsys_state) may be created and destroyed dynamically over the lifetime of a cgroup, which is different from the current state where all css's are allocated and destroyed together with the associated cgroup. This in turn means that cgroup_css() should be synchronized and may return NULL, making it more cumbersome to use. * Differing levels of per-subsystem granularity in the unified hierarchy means that the task and descendant iterators should behave differently depending on the specific subsystem the iteration is being performed for. * In majority of the cases, subsystems only care about its part in the cgroup hierarchy - ie. the hierarchy of css's. Subsystem methods often obtain the matching css pointer from the cgroup and don't bother with the cgroup pointer itself. Passing around css fits much better. This patch converts all cgroup_subsys methods to take @css instead of @cgroup. The conversions are mostly straight-forward. A few noteworthy changes are * ->css_alloc() now takes css of the parent cgroup rather than the pointer to the new cgroup as the css for the new cgroup doesn't exist yet. Knowing the parent css is enough for all the existing subsystems. * In kernel/cgroup.c::offline_css(), unnecessary open coded css dereference is replaced with local variable access. This patch shouldn't cause any behavior differences. v2: Unnecessary explicit cgrp->subsys[] deref in css_online() replaced with local variable @css as suggested by Li Zefan. Rebased on top of new for-3.12 which includes for-3.11-fixes so that ->css_free() invocation added by da0a12caff ("cgroup: fix a leak when percpu_ref_init() fails") is converted too. Suggested by Li Zefan. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Li Zefan <lizefan@huawei.com> Acked-by: Michal Hocko <mhocko@suse.cz> Acked-by: Vivek Goyal <vgoyal@redhat.com> Acked-by: Aristeu Rozanski <aris@redhat.com> Acked-by: Daniel Wagner <daniel.wagner@bmw-carit.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Balbir Singh <bsingharora@gmail.com> Cc: Matt Helsley <matthltc@us.ibm.com> Cc: Jens Axboe <axboe@kernel.dk> Cc: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/cgroup_freezer.c')
-rw-r--r--kernel/cgroup_freezer.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c
index 657a73cd44c4..f03a85719c3c 100644
--- a/kernel/cgroup_freezer.c
+++ b/kernel/cgroup_freezer.c
@@ -91,7 +91,8 @@ static const char *freezer_state_strs(unsigned int state)
91 91
92struct cgroup_subsys freezer_subsys; 92struct cgroup_subsys freezer_subsys;
93 93
94static struct cgroup_subsys_state *freezer_css_alloc(struct cgroup *cgroup) 94static struct cgroup_subsys_state *
95freezer_css_alloc(struct cgroup_subsys_state *parent_css)
95{ 96{
96 struct freezer *freezer; 97 struct freezer *freezer;
97 98
@@ -104,16 +105,16 @@ static struct cgroup_subsys_state *freezer_css_alloc(struct cgroup *cgroup)
104} 105}
105 106
106/** 107/**
107 * freezer_css_online - commit creation of a freezer cgroup 108 * freezer_css_online - commit creation of a freezer css
108 * @cgroup: cgroup being created 109 * @css: css being created
109 * 110 *
110 * We're committing to creation of @cgroup. Mark it online and inherit 111 * We're committing to creation of @css. Mark it online and inherit
111 * parent's freezing state while holding both parent's and our 112 * parent's freezing state while holding both parent's and our
112 * freezer->lock. 113 * freezer->lock.
113 */ 114 */
114static int freezer_css_online(struct cgroup *cgroup) 115static int freezer_css_online(struct cgroup_subsys_state *css)
115{ 116{
116 struct freezer *freezer = cgroup_freezer(cgroup); 117 struct freezer *freezer = css_freezer(css);
117 struct freezer *parent = parent_freezer(freezer); 118 struct freezer *parent = parent_freezer(freezer);
118 119
119 /* 120 /*
@@ -140,15 +141,15 @@ static int freezer_css_online(struct cgroup *cgroup)
140} 141}
141 142
142/** 143/**
143 * freezer_css_offline - initiate destruction of @cgroup 144 * freezer_css_offline - initiate destruction of a freezer css
144 * @cgroup: cgroup being destroyed 145 * @css: css being destroyed
145 * 146 *
146 * @cgroup is going away. Mark it dead and decrement system_freezing_count 147 * @css is going away. Mark it dead and decrement system_freezing_count if
147 * if it was holding one. 148 * it was holding one.
148 */ 149 */
149static void freezer_css_offline(struct cgroup *cgroup) 150static void freezer_css_offline(struct cgroup_subsys_state *css)
150{ 151{
151 struct freezer *freezer = cgroup_freezer(cgroup); 152 struct freezer *freezer = css_freezer(css);
152 153
153 spin_lock_irq(&freezer->lock); 154 spin_lock_irq(&freezer->lock);
154 155
@@ -160,9 +161,9 @@ static void freezer_css_offline(struct cgroup *cgroup)
160 spin_unlock_irq(&freezer->lock); 161 spin_unlock_irq(&freezer->lock);
161} 162}
162 163
163static void freezer_css_free(struct cgroup *cgroup) 164static void freezer_css_free(struct cgroup_subsys_state *css)
164{ 165{
165 kfree(cgroup_freezer(cgroup)); 166 kfree(css_freezer(css));
166} 167}
167 168
168/* 169/*
@@ -174,25 +175,26 @@ static void freezer_css_free(struct cgroup *cgroup)
174 * @freezer->lock. freezer_attach() makes the new tasks conform to the 175 * @freezer->lock. freezer_attach() makes the new tasks conform to the
175 * current state and all following state changes can see the new tasks. 176 * current state and all following state changes can see the new tasks.
176 */ 177 */
177static void freezer_attach(struct cgroup *new_cgrp, struct cgroup_taskset *tset) 178static void freezer_attach(struct cgroup_subsys_state *new_css,
179 struct cgroup_taskset *tset)
178{ 180{
179 struct freezer *freezer = cgroup_freezer(new_cgrp); 181 struct freezer *freezer = css_freezer(new_css);
180 struct task_struct *task; 182 struct task_struct *task;
181 bool clear_frozen = false; 183 bool clear_frozen = false;
182 184
183 spin_lock_irq(&freezer->lock); 185 spin_lock_irq(&freezer->lock);
184 186
185 /* 187 /*
186 * Make the new tasks conform to the current state of @new_cgrp. 188 * Make the new tasks conform to the current state of @new_css.
187 * For simplicity, when migrating any task to a FROZEN cgroup, we 189 * For simplicity, when migrating any task to a FROZEN cgroup, we
188 * revert it to FREEZING and let update_if_frozen() determine the 190 * revert it to FREEZING and let update_if_frozen() determine the
189 * correct state later. 191 * correct state later.
190 * 192 *
191 * Tasks in @tset are on @new_cgrp but may not conform to its 193 * Tasks in @tset are on @new_css but may not conform to its
192 * current state before executing the following - !frozen tasks may 194 * current state before executing the following - !frozen tasks may
193 * be visible in a FROZEN cgroup and frozen tasks in a THAWED one. 195 * be visible in a FROZEN cgroup and frozen tasks in a THAWED one.
194 */ 196 */
195 cgroup_taskset_for_each(task, new_cgrp, tset) { 197 cgroup_taskset_for_each(task, new_css->cgroup, tset) {
196 if (!(freezer->state & CGROUP_FREEZING)) { 198 if (!(freezer->state & CGROUP_FREEZING)) {
197 __thaw_task(task); 199 __thaw_task(task);
198 } else { 200 } else {