/*
* State maintained by the cgroup system to allow subsystems
* to be "busy". Should be accessed via css_get(),
- * css_tryget() and and css_put().
+ * css_tryget() and css_put().
*/
atomic_t refcnt;
/* bits in struct cgroup_subsys_state flags field */
enum {
- CSS_ROOT, /* This CSS is the root of the subsystem */
+ CSS_ROOT = (1 << 0), /* this CSS is the root of the subsystem */
+ CSS_ONLINE = (1 << 1), /* between ->css_online() and ->css_offline() */
};
/* Caller must verify that the css is not for root cgroup */
static inline void css_get(struct cgroup_subsys_state *css)
{
/* We don't need to reference count the root state */
- if (!test_bit(CSS_ROOT, &css->flags))
+ if (!(css->flags & CSS_ROOT))
__css_get(css, 1);
}
extern bool __css_tryget(struct cgroup_subsys_state *css);
static inline bool css_tryget(struct cgroup_subsys_state *css)
{
- if (test_bit(CSS_ROOT, &css->flags))
+ if (css->flags & CSS_ROOT)
return true;
return __css_tryget(css);
}
extern void __css_put(struct cgroup_subsys_state *css);
static inline void css_put(struct cgroup_subsys_state *css)
{
- if (!test_bit(CSS_ROOT, &css->flags))
+ if (!(css->flags & CSS_ROOT))
__css_put(css);
}
/* Control Group requires release notifications to userspace */
CGRP_NOTIFY_ON_RELEASE,
/*
- * Clone cgroup values when creating a new child cgroup
+ * Clone the parent's configuration when creating a new child
+ * cpuset cgroup. For historical reasons, this option can be
+ * specified at mount time and thus is implemented here.
*/
- CGRP_CLONE_CHILDREN,
+ CGRP_CPUSET_CLONE_CHILDREN,
};
struct cgroup {
*/
atomic_t count;
+ int id; /* ida allocated in-hierarchy ID */
+
/*
* We link our 'sibling' struct into our parent's 'children'.
* Our children link their 'sibling' into our 'children'.
struct list_head files; /* my files */
struct cgroup *parent; /* my parent */
- struct dentry __rcu *dentry; /* cgroup fs entry, RCU protected */
+ struct dentry *dentry; /* cgroup fs entry, RCU protected */
/* Private pointers for each registered subsystem */
struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
/* cftype->flags */
#define CFTYPE_ONLY_ON_ROOT (1U << 0) /* only create on root cg */
-#define CFTYPE_NOT_ON_ROOT (1U << 1) /* don't create onp root cg */
+#define CFTYPE_NOT_ON_ROOT (1U << 1) /* don't create on root cg */
#define MAX_CFTYPE_NAME 64
*/
struct cgroup_subsys {
- struct cgroup_subsys_state *(*create)(struct cgroup *cgrp);
- void (*post_create)(struct cgroup *cgrp);
- void (*pre_destroy)(struct cgroup *cgrp);
- void (*destroy)(struct cgroup *cgrp);
+ struct cgroup_subsys_state *(*css_alloc)(struct cgroup *cgrp);
+ int (*css_online)(struct cgroup *cgrp);
+ void (*css_offline)(struct cgroup *cgrp);
+ void (*css_free)(struct cgroup *cgrp);
+
int (*can_attach)(struct cgroup *cgrp, struct cgroup_taskset *tset);
void (*cancel_attach)(struct cgroup *cgrp, struct cgroup_taskset *tset);
void (*attach)(struct cgroup *cgrp, struct cgroup_taskset *tset);
void (*fork)(struct task_struct *task);
void (*exit)(struct cgroup *cgrp, struct cgroup *old_cgrp,
struct task_struct *task);
- void (*post_clone)(struct cgroup *cgrp);
void (*bind)(struct cgroup *root);
int subsys_id;
* @cgroup: cgroup whose children to walk
*
* Walk @cgroup's children. Must be called under rcu_read_lock(). A child
- * cgroup which hasn't finished ->post_create() or already has finished
- * ->pre_destroy() may show up during traversal and it's each subsystem's
+ * cgroup which hasn't finished ->css_online() or already has finished
+ * ->css_offline() may show up during traversal and it's each subsystem's
* responsibility to verify that each @pos is alive.
*
- * If a subsystem synchronizes against the parent in its ->post_create()
- * and before starting iterating, a cgroup which finished ->post_create()
- * is guaranteed to be visible in the future iterations.
+ * If a subsystem synchronizes against the parent in its ->css_online() and
+ * before starting iterating, a cgroup which finished ->css_online() is
+ * guaranteed to be visible in the future iterations.
*/
#define cgroup_for_each_child(pos, cgroup) \
list_for_each_entry_rcu(pos, &(cgroup)->children, sibling)
* @cgroup: cgroup whose descendants to walk
*
* Walk @cgroup's descendants. Must be called under rcu_read_lock(). A
- * descendant cgroup which hasn't finished ->post_create() or already has
- * finished ->pre_destroy() may show up during traversal and it's each
+ * descendant cgroup which hasn't finished ->css_online() or already has
+ * finished ->css_offline() may show up during traversal and it's each
* subsystem's responsibility to verify that each @pos is alive.
*
- * If a subsystem synchronizes against the parent in its ->post_create()
- * and before starting iterating, and synchronizes against @pos on each
- * iteration, any descendant cgroup which finished ->post_create() is
+ * If a subsystem synchronizes against the parent in its ->css_online() and
+ * before starting iterating, and synchronizes against @pos on each
+ * iteration, any descendant cgroup which finished ->css_offline() is
* guaranteed to be visible in the future iterations.
*
* In other words, the following guarantees that a descendant can't escape
* state updates of its ancestors.
*
- * my_post_create(@cgrp)
+ * my_online(@cgrp)
* {
* Lock @cgrp->parent and @cgrp;
* Inherit state from @cgrp->parent;
* iteration should lock and unlock both @pos->parent and @pos.
*
* Alternatively, a subsystem may choose to use a single global lock to
- * synchronize ->post_create() and ->pre_destroy() against tree-walking
+ * synchronize ->css_online() and ->css_offline() against tree-walking
* operations.
*/
#define cgroup_for_each_descendant_pre(pos, cgroup) \