diff options
Diffstat (limited to 'include/linux/cgroup.h')
| -rw-r--r-- | include/linux/cgroup.h | 54 | 
1 files changed, 48 insertions, 6 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index c9bbcb2a75a..8f78073d7ca 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -37,16 +37,24 @@ extern void cgroup_post_fork(struct task_struct *p);  extern void cgroup_exit(struct task_struct *p, int run_callbacks);  extern int cgroupstats_build(struct cgroupstats *stats,  				struct dentry *dentry); +extern int cgroup_load_subsys(struct cgroup_subsys *ss); +extern void cgroup_unload_subsys(struct cgroup_subsys *ss);  extern const struct file_operations proc_cgroup_operations; -/* Define the enumeration of all cgroup subsystems */ +/* Define the enumeration of all builtin cgroup subsystems */  #define SUBSYS(_x) _x ## _subsys_id,  enum cgroup_subsys_id {  #include <linux/cgroup_subsys.h> -	CGROUP_SUBSYS_COUNT +	CGROUP_BUILTIN_SUBSYS_COUNT  };  #undef SUBSYS +/* + * This define indicates the maximum number of subsystems that can be loaded + * at once. We limit to this many since cgroupfs_root has subsys_bits to keep + * track of all of them. + */ +#define CGROUP_SUBSYS_COUNT (BITS_PER_BYTE*sizeof(unsigned long))  /* Per-subsystem/per-cgroup state maintained by the system. */  struct cgroup_subsys_state { @@ -76,6 +84,12 @@ enum {  	CSS_REMOVED, /* This CSS is dead */  }; +/* Caller must verify that the css is not for root cgroup */ +static inline void __css_get(struct cgroup_subsys_state *css, int count) +{ +	atomic_add(count, &css->refcnt); +} +  /*   * Call css_get() to hold a reference on the css; it can be used   * for a reference obtained via: @@ -87,7 +101,7 @@ 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)) -		atomic_inc(&css->refcnt); +		__css_get(css, 1);  }  static inline bool css_is_removed(struct cgroup_subsys_state *css) @@ -118,11 +132,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); +extern void __css_put(struct cgroup_subsys_state *css, int count);  static inline void css_put(struct cgroup_subsys_state *css)  {  	if (!test_bit(CSS_ROOT, &css->flags)) -		__css_put(css); +		__css_put(css, 1);  }  /* bits in struct cgroup flags field */ @@ -221,6 +235,10 @@ struct cgroup {  	/* For RCU-protected deletion */  	struct rcu_head rcu_head; + +	/* List of events which userspace want to recieve */ +	struct list_head event_list; +	spinlock_t event_list_lock;  };  /* @@ -258,7 +276,8 @@ struct css_set {  	/*  	 * Set of subsystem states, one for each subsystem. This array  	 * is immutable after creation apart from the init_css_set -	 * during subsystem registration (at boot time). +	 * during subsystem registration (at boot time) and modular subsystem +	 * loading/unloading.  	 */  	struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; @@ -363,6 +382,23 @@ struct cftype {  	int (*trigger)(struct cgroup *cgrp, unsigned int event);  	int (*release)(struct inode *inode, struct file *file); + +	/* +	 * register_event() callback will be used to add new userspace +	 * waiter for changes related to the cftype. Implement it if +	 * you want to provide this functionality. Use eventfd_signal() +	 * on eventfd to send notification to userspace. +	 */ +	int (*register_event)(struct cgroup *cgrp, struct cftype *cft, +			struct eventfd_ctx *eventfd, const char *args); +	/* +	 * unregister_event() callback will be called when userspace +	 * closes the eventfd or on cgroup removing. +	 * This callback must be implemented, if you want provide +	 * notification functionality. +	 */ +	int (*unregister_event)(struct cgroup *cgrp, struct cftype *cft, +			struct eventfd_ctx *eventfd);  };  struct cgroup_scanner { @@ -428,6 +464,8 @@ struct cgroup_subsys {  	void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp);  	int (*can_attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,  			  struct task_struct *tsk, bool threadgroup); +	void (*cancel_attach)(struct cgroup_subsys *ss, struct cgroup *cgrp, +			  struct task_struct *tsk, bool threadgroup);  	void (*attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,  			struct cgroup *old_cgrp, struct task_struct *tsk,  			bool threadgroup); @@ -472,6 +510,9 @@ struct cgroup_subsys {  	/* used when use_id == true */  	struct idr idr;  	spinlock_t id_lock; + +	/* should be defined only by modular subsystems */ +	struct module *module;  };  #define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys; @@ -489,6 +530,7 @@ static inline struct cgroup_subsys_state *task_subsys_state(  {  	return rcu_dereference_check(task->cgroups->subsys[subsys_id],  				     rcu_read_lock_held() || +				     lockdep_is_held(&task->alloc_lock) ||  				     cgroup_lock_is_held());  }  |