Skip to content

Commit ba7b238

Browse files
committed
Merge branch 'for-4.12-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup fixes from Tejun Heo: "Two cgroup fixes. One to address RCU delay of cpuset removal affecting userland visible behaviors. The other fixes a race condition between controller disable and cgroup removal" * 'for-4.12-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: cpuset: consider dying css as offline cgroup: Prevent kill_css() from being called more than once
2 parents e543c8a + 41c2570 commit ba7b238

File tree

4 files changed

+28
-2
lines changed

4 files changed

+28
-2
lines changed

include/linux/cgroup-defs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ enum {
4848
CSS_ONLINE = (1 << 1), /* between ->css_online() and ->css_offline() */
4949
CSS_RELEASED = (1 << 2), /* refcnt reached zero, released */
5050
CSS_VISIBLE = (1 << 3), /* css is visible to userland */
51+
CSS_DYING = (1 << 4), /* css is dying */
5152
};
5253

5354
/* bits in struct cgroup flags field */

include/linux/cgroup.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,26 @@ static inline bool css_tryget_online(struct cgroup_subsys_state *css)
343343
return true;
344344
}
345345

346+
/**
347+
* css_is_dying - test whether the specified css is dying
348+
* @css: target css
349+
*
350+
* Test whether @css is in the process of offlining or already offline. In
351+
* most cases, ->css_online() and ->css_offline() callbacks should be
352+
* enough; however, the actual offline operations are RCU delayed and this
353+
* test returns %true also when @css is scheduled to be offlined.
354+
*
355+
* This is useful, for example, when the use case requires synchronous
356+
* behavior with respect to cgroup removal. cgroup removal schedules css
357+
* offlining but the css can seem alive while the operation is being
358+
* delayed. If the delay affects user visible semantics, this test can be
359+
* used to resolve the situation.
360+
*/
361+
static inline bool css_is_dying(struct cgroup_subsys_state *css)
362+
{
363+
return !(css->flags & CSS_NO_REF) && percpu_ref_is_dying(&css->refcnt);
364+
}
365+
346366
/**
347367
* css_put - put a css reference
348368
* @css: target css

kernel/cgroup/cgroup.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4265,6 +4265,11 @@ static void kill_css(struct cgroup_subsys_state *css)
42654265
{
42664266
lockdep_assert_held(&cgroup_mutex);
42674267

4268+
if (css->flags & CSS_DYING)
4269+
return;
4270+
4271+
css->flags |= CSS_DYING;
4272+
42684273
/*
42694274
* This must happen before css is disassociated with its cgroup.
42704275
* See seq_css() for details.

kernel/cgroup/cpuset.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,9 @@ typedef enum {
176176
} cpuset_flagbits_t;
177177

178178
/* convenient tests for these bits */
179-
static inline bool is_cpuset_online(const struct cpuset *cs)
179+
static inline bool is_cpuset_online(struct cpuset *cs)
180180
{
181-
return test_bit(CS_ONLINE, &cs->flags);
181+
return test_bit(CS_ONLINE, &cs->flags) && !css_is_dying(&cs->css);
182182
}
183183

184184
static inline int is_cpu_exclusive(const struct cpuset *cs)

0 commit comments

Comments
 (0)