aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/cgroup.h33
-rw-r--r--kernel/cgroup.c132
2 files changed, 162 insertions, 3 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index ad2a14680b7f..af6211c7a42b 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -192,6 +192,7 @@ struct cgroup {
192 struct list_head css_sets; 192 struct list_head css_sets;
193 193
194 struct list_head allcg_node; /* cgroupfs_root->allcg_list */ 194 struct list_head allcg_node; /* cgroupfs_root->allcg_list */
195 struct list_head cft_q_node; /* used during cftype add/rm */
195 196
196 /* 197 /*
197 * Linked list running through all cgroups that can 198 * Linked list running through all cgroups that can
@@ -277,11 +278,17 @@ struct cgroup_map_cb {
277 * - the 'cftype' of the file is file->f_dentry->d_fsdata 278 * - the 'cftype' of the file is file->f_dentry->d_fsdata
278 */ 279 */
279 280
280#define MAX_CFTYPE_NAME 64 281/* cftype->flags */
282#define CFTYPE_ONLY_ON_ROOT (1U << 0) /* only create on root cg */
283#define CFTYPE_NOT_ON_ROOT (1U << 1) /* don't create onp root cg */
284
285#define MAX_CFTYPE_NAME 64
286
281struct cftype { 287struct cftype {
282 /* 288 /*
283 * By convention, the name should begin with the name of the 289 * By convention, the name should begin with the name of the
284 * subsystem, followed by a period 290 * subsystem, followed by a period. Zero length string indicates
291 * end of cftype array.
285 */ 292 */
286 char name[MAX_CFTYPE_NAME]; 293 char name[MAX_CFTYPE_NAME];
287 int private; 294 int private;
@@ -297,6 +304,9 @@ struct cftype {
297 */ 304 */
298 size_t max_write_len; 305 size_t max_write_len;
299 306
307 /* CFTYPE_* flags */
308 unsigned int flags;
309
300 int (*open)(struct inode *inode, struct file *file); 310 int (*open)(struct inode *inode, struct file *file);
301 ssize_t (*read)(struct cgroup *cgrp, struct cftype *cft, 311 ssize_t (*read)(struct cgroup *cgrp, struct cftype *cft,
302 struct file *file, 312 struct file *file,
@@ -375,6 +385,16 @@ struct cftype {
375 struct eventfd_ctx *eventfd); 385 struct eventfd_ctx *eventfd);
376}; 386};
377 387
388/*
389 * cftype_sets describe cftypes belonging to a subsystem and are chained at
390 * cgroup_subsys->cftsets. Each cftset points to an array of cftypes
391 * terminated by zero length name.
392 */
393struct cftype_set {
394 struct list_head node; /* chained at subsys->cftsets */
395 const struct cftype *cfts;
396};
397
378struct cgroup_scanner { 398struct cgroup_scanner {
379 struct cgroup *cg; 399 struct cgroup *cg;
380 int (*test_task)(struct task_struct *p, struct cgroup_scanner *scan); 400 int (*test_task)(struct task_struct *p, struct cgroup_scanner *scan);
@@ -400,6 +420,8 @@ int cgroup_add_files(struct cgroup *cgrp,
400 const struct cftype cft[], 420 const struct cftype cft[],
401 int count); 421 int count);
402 422
423int cgroup_add_cftypes(struct cgroup_subsys *ss, const struct cftype *cfts);
424
403int cgroup_is_removed(const struct cgroup *cgrp); 425int cgroup_is_removed(const struct cgroup *cgrp);
404 426
405int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen); 427int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen);
@@ -502,6 +524,13 @@ struct cgroup_subsys {
502 struct idr idr; 524 struct idr idr;
503 spinlock_t id_lock; 525 spinlock_t id_lock;
504 526
527 /* list of cftype_sets */
528 struct list_head cftsets;
529
530 /* base cftypes, automatically [de]registered with subsys itself */
531 struct cftype *base_cftypes;
532 struct cftype_set base_cftset;
533
505 /* should be defined only by modular subsystems */ 534 /* should be defined only by modular subsystems */
506 struct module *module; 535 struct module *module;
507}; 536};
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index db4319c030d0..df8fb82ef350 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -2623,8 +2623,14 @@ int cgroup_add_file(struct cgroup *cgrp,
2623 struct dentry *dentry; 2623 struct dentry *dentry;
2624 int error; 2624 int error;
2625 umode_t mode; 2625 umode_t mode;
2626
2627 char name[MAX_CGROUP_TYPE_NAMELEN + MAX_CFTYPE_NAME + 2] = { 0 }; 2626 char name[MAX_CGROUP_TYPE_NAMELEN + MAX_CFTYPE_NAME + 2] = { 0 };
2627
2628 /* does @cft->flags tell us to skip creation on @cgrp? */
2629 if ((cft->flags & CFTYPE_NOT_ON_ROOT) && !cgrp->parent)
2630 return 0;
2631 if ((cft->flags & CFTYPE_ONLY_ON_ROOT) && cgrp->parent)
2632 return 0;
2633
2628 if (subsys && !test_bit(ROOT_NOPREFIX, &cgrp->root->flags)) { 2634 if (subsys && !test_bit(ROOT_NOPREFIX, &cgrp->root->flags)) {
2629 strcpy(name, subsys->name); 2635 strcpy(name, subsys->name);
2630 strcat(name, "."); 2636 strcat(name, ".");
@@ -2660,6 +2666,95 @@ int cgroup_add_files(struct cgroup *cgrp,
2660} 2666}
2661EXPORT_SYMBOL_GPL(cgroup_add_files); 2667EXPORT_SYMBOL_GPL(cgroup_add_files);
2662 2668
2669static DEFINE_MUTEX(cgroup_cft_mutex);
2670
2671static void cgroup_cfts_prepare(void)
2672 __acquires(&cgroup_cft_mutex) __acquires(&cgroup_mutex)
2673{
2674 /*
2675 * Thanks to the entanglement with vfs inode locking, we can't walk
2676 * the existing cgroups under cgroup_mutex and create files.
2677 * Instead, we increment reference on all cgroups and build list of
2678 * them using @cgrp->cft_q_node. Grab cgroup_cft_mutex to ensure
2679 * exclusive access to the field.
2680 */
2681 mutex_lock(&cgroup_cft_mutex);
2682 mutex_lock(&cgroup_mutex);
2683}
2684
2685static void cgroup_cfts_commit(struct cgroup_subsys *ss,
2686 const struct cftype *cfts)
2687 __releases(&cgroup_mutex) __releases(&cgroup_cft_mutex)
2688{
2689 LIST_HEAD(pending);
2690 struct cgroup *cgrp, *n;
2691 int count = 0;
2692
2693 while (cfts[count].name[0] != '\0')
2694 count++;
2695
2696 /* %NULL @cfts indicates abort and don't bother if @ss isn't attached */
2697 if (cfts && ss->root != &rootnode) {
2698 list_for_each_entry(cgrp, &ss->root->allcg_list, allcg_node) {
2699 dget(cgrp->dentry);
2700 list_add_tail(&cgrp->cft_q_node, &pending);
2701 }
2702 }
2703
2704 mutex_unlock(&cgroup_mutex);
2705
2706 /*
2707 * All new cgroups will see @cfts update on @ss->cftsets. Add/rm
2708 * files for all cgroups which were created before.
2709 */
2710 list_for_each_entry_safe(cgrp, n, &pending, cft_q_node) {
2711 struct inode *inode = cgrp->dentry->d_inode;
2712
2713 mutex_lock(&inode->i_mutex);
2714 mutex_lock(&cgroup_mutex);
2715 if (!cgroup_is_removed(cgrp))
2716 cgroup_add_files(cgrp, ss, cfts, count);
2717 mutex_unlock(&cgroup_mutex);
2718 mutex_unlock(&inode->i_mutex);
2719
2720 list_del_init(&cgrp->cft_q_node);
2721 dput(cgrp->dentry);
2722 }
2723
2724 mutex_unlock(&cgroup_cft_mutex);
2725}
2726
2727/**
2728 * cgroup_add_cftypes - add an array of cftypes to a subsystem
2729 * @ss: target cgroup subsystem
2730 * @cfts: zero-length name terminated array of cftypes
2731 *
2732 * Register @cfts to @ss. Files described by @cfts are created for all
2733 * existing cgroups to which @ss is attached and all future cgroups will
2734 * have them too. This function can be called anytime whether @ss is
2735 * attached or not.
2736 *
2737 * Returns 0 on successful registration, -errno on failure. Note that this
2738 * function currently returns 0 as long as @cfts registration is successful
2739 * even if some file creation attempts on existing cgroups fail.
2740 */
2741int cgroup_add_cftypes(struct cgroup_subsys *ss, const struct cftype *cfts)
2742{
2743 struct cftype_set *set;
2744
2745 set = kzalloc(sizeof(*set), GFP_KERNEL);
2746 if (!set)
2747 return -ENOMEM;
2748
2749 cgroup_cfts_prepare();
2750 set->cfts = cfts;
2751 list_add_tail(&set->node, &ss->cftsets);
2752 cgroup_cfts_commit(ss, cfts);
2753
2754 return 0;
2755}
2756EXPORT_SYMBOL_GPL(cgroup_add_cftypes);
2757
2663/** 2758/**
2664 * cgroup_task_count - count the number of tasks in a cgroup. 2759 * cgroup_task_count - count the number of tasks in a cgroup.
2665 * @cgrp: the cgroup in question 2760 * @cgrp: the cgroup in question
@@ -3660,10 +3755,25 @@ static int cgroup_populate_dir(struct cgroup *cgrp)
3660 return err; 3755 return err;
3661 } 3756 }
3662 3757
3758 /* process cftsets of each subsystem */
3663 for_each_subsys(cgrp->root, ss) { 3759 for_each_subsys(cgrp->root, ss) {
3760 struct cftype_set *set;
3761
3664 if (ss->populate && (err = ss->populate(ss, cgrp)) < 0) 3762 if (ss->populate && (err = ss->populate(ss, cgrp)) < 0)
3665 return err; 3763 return err;
3764
3765 list_for_each_entry(set, &ss->cftsets, node) {
3766 const struct cftype *cft;
3767
3768 for (cft = set->cfts; cft->name[0] != '\0'; cft++) {
3769 err = cgroup_add_file(cgrp, ss, cft);
3770 if (err)
3771 pr_warning("cgroup_populate_dir: failed to create %s, err=%d\n",
3772 cft->name, err);
3773 }
3774 }
3666 } 3775 }
3776
3667 /* This cgroup is ready now */ 3777 /* This cgroup is ready now */
3668 for_each_subsys(cgrp->root, ss) { 3778 for_each_subsys(cgrp->root, ss) {
3669 struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id]; 3779 struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id];
@@ -4034,12 +4144,29 @@ again:
4034 return 0; 4144 return 0;
4035} 4145}
4036 4146
4147static void __init_or_module cgroup_init_cftsets(struct cgroup_subsys *ss)
4148{
4149 INIT_LIST_HEAD(&ss->cftsets);
4150
4151 /*
4152 * base_cftset is embedded in subsys itself, no need to worry about
4153 * deregistration.
4154 */
4155 if (ss->base_cftypes) {
4156 ss->base_cftset.cfts = ss->base_cftypes;
4157 list_add_tail(&ss->base_cftset.node, &ss->cftsets);
4158 }
4159}
4160
4037static void __init cgroup_init_subsys(struct cgroup_subsys *ss) 4161static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
4038{ 4162{
4039 struct cgroup_subsys_state *css; 4163 struct cgroup_subsys_state *css;
4040 4164
4041 printk(KERN_INFO "Initializing cgroup subsys %s\n", ss->name); 4165 printk(KERN_INFO "Initializing cgroup subsys %s\n", ss->name);
4042 4166
4167 /* init base cftset */
4168 cgroup_init_cftsets(ss);
4169
4043 /* Create the top cgroup state for this subsystem */ 4170 /* Create the top cgroup state for this subsystem */
4044 list_add(&ss->sibling, &rootnode.subsys_list); 4171 list_add(&ss->sibling, &rootnode.subsys_list);
4045 ss->root = &rootnode; 4172 ss->root = &rootnode;
@@ -4109,6 +4236,9 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
4109 return 0; 4236 return 0;
4110 } 4237 }
4111 4238
4239 /* init base cftset */
4240 cgroup_init_cftsets(ss);
4241
4112 /* 4242 /*
4113 * need to register a subsys id before anything else - for example, 4243 * need to register a subsys id before anything else - for example,
4114 * init_cgroup_css needs it. 4244 * init_cgroup_css needs it.