diff options
Diffstat (limited to 'include/linux/cgroup.h')
| -rw-r--r-- | include/linux/cgroup.h | 81 | 
1 files changed, 55 insertions, 26 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 5a85b3415c1..d3f5fba2c15 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -16,6 +16,7 @@  #include <linux/prio_heap.h>  #include <linux/rwsem.h>  #include <linux/idr.h> +#include <linux/workqueue.h>  #ifdef CONFIG_CGROUPS @@ -76,12 +77,16 @@ struct cgroup_subsys_state {  	unsigned long flags;  	/* ID for this css, if possible */  	struct css_id __rcu *id; + +	/* Used to put @cgroup->dentry on the last css_put() */ +	struct work_struct dput_work;  };  /* bits in struct cgroup_subsys_state flags field */  enum {  	CSS_ROOT, /* This CSS is the root of the subsystem */  	CSS_REMOVED, /* This CSS is dead */ +	CSS_CLEAR_CSS_REFS,		/* @ss->__DEPRECATED_clear_css_refs */  };  /* Caller must verify that the css is not for root cgroup */ @@ -115,16 +120,12 @@ static inline bool css_is_removed(struct cgroup_subsys_state *css)   * the css has been destroyed.   */ +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))  		return true; -	while (!atomic_inc_not_zero(&css->refcnt)) { -		if (test_bit(CSS_REMOVED, &css->flags)) -			return false; -		cpu_relax(); -	} -	return true; +	return __css_tryget(css);  }  /* @@ -132,11 +133,11 @@ static inline bool css_tryget(struct cgroup_subsys_state *css)   * css_get() or css_tryget()   */ -extern void __css_put(struct cgroup_subsys_state *css, int count); +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)) -		__css_put(css, 1); +		__css_put(css);  }  /* bits in struct cgroup flags field */ @@ -175,6 +176,7 @@ struct cgroup {  	 */  	struct list_head sibling;	/* my parent's children */  	struct list_head children;	/* my children */ +	struct list_head files;		/* my files */  	struct cgroup *parent;		/* my parent */  	struct dentry __rcu *dentry;	/* cgroup fs entry, RCU protected */ @@ -191,6 +193,9 @@ struct cgroup {  	 */  	struct list_head css_sets; +	struct list_head allcg_node;	/* cgroupfs_root->allcg_list */ +	struct list_head cft_q_node;	/* used during cftype add/rm */ +  	/*  	 * Linked list running through all cgroups that can  	 * potentially be reaped by the release agent. Protected by @@ -275,11 +280,17 @@ struct cgroup_map_cb {   *	- the 'cftype' of the file is file->f_dentry->d_fsdata   */ -#define MAX_CFTYPE_NAME 64 +/* 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 MAX_CFTYPE_NAME		64 +  struct cftype {  	/*  	 * By convention, the name should begin with the name of the -	 * subsystem, followed by a period +	 * subsystem, followed by a period.  Zero length string indicates +	 * end of cftype array.  	 */  	char name[MAX_CFTYPE_NAME];  	int private; @@ -295,6 +306,9 @@ struct cftype {  	 */  	size_t max_write_len; +	/* CFTYPE_* flags */ +	unsigned int flags; +  	int (*open)(struct inode *inode, struct file *file);  	ssize_t (*read)(struct cgroup *cgrp, struct cftype *cft,  			struct file *file, @@ -373,6 +387,16 @@ struct cftype {  			struct eventfd_ctx *eventfd);  }; +/* + * cftype_sets describe cftypes belonging to a subsystem and are chained at + * cgroup_subsys->cftsets.  Each cftset points to an array of cftypes + * terminated by zero length name. + */ +struct cftype_set { +	struct list_head		node;	/* chained at subsys->cftsets */ +	const struct cftype		*cfts; +}; +  struct cgroup_scanner {  	struct cgroup *cg;  	int (*test_task)(struct task_struct *p, struct cgroup_scanner *scan); @@ -382,21 +406,8 @@ struct cgroup_scanner {  	void *data;  }; -/* - * Add a new file to the given cgroup directory. Should only be - * called by subsystems from within a populate() method - */ -int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys, -		       const struct cftype *cft); - -/* - * Add a set of new files to the given cgroup directory. Should - * only be called by subsystems from within a populate() method - */ -int cgroup_add_files(struct cgroup *cgrp, -			struct cgroup_subsys *subsys, -			const struct cftype cft[], -			int count); +int cgroup_add_cftypes(struct cgroup_subsys *ss, const struct cftype *cfts); +int cgroup_rm_cftypes(struct cgroup_subsys *ss, const struct cftype *cfts);  int cgroup_is_removed(const struct cgroup *cgrp); @@ -461,7 +472,6 @@ struct cgroup_subsys {  	void (*fork)(struct task_struct *task);  	void (*exit)(struct cgroup *cgrp, struct cgroup *old_cgrp,  		     struct task_struct *task); -	int (*populate)(struct cgroup_subsys *ss, struct cgroup *cgrp);  	void (*post_clone)(struct cgroup *cgrp);  	void (*bind)(struct cgroup *root); @@ -474,6 +484,18 @@ struct cgroup_subsys {  	 * (not available in early_init time.)  	 */  	bool use_id; + +	/* +	 * If %true, cgroup removal will try to clear css refs by retrying +	 * ss->pre_destroy() until there's no css ref left.  This behavior +	 * is strictly for backward compatibility and will be removed as +	 * soon as the current user (memcg) is updated. +	 * +	 * If %false, ss->pre_destroy() can't fail and cgroup removal won't +	 * wait for css refs to drop to zero before proceeding. +	 */ +	bool __DEPRECATED_clear_css_refs; +  #define MAX_CGROUP_TYPE_NAMELEN 32  	const char *name; @@ -500,6 +522,13 @@ struct cgroup_subsys {  	struct idr idr;  	spinlock_t id_lock; +	/* list of cftype_sets */ +	struct list_head cftsets; + +	/* base cftypes, automatically [de]registered with subsys itself */ +	struct cftype *base_cftypes; +	struct cftype_set base_cftset; +  	/* should be defined only by modular subsystems */  	struct module *module;  };  |