diff options
author | Tejun Heo <tj@kernel.org> | 2014-02-12 09:29:50 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2014-02-12 09:29:50 -0500 |
commit | e61734c55c24cdf11b07e52a74aec4dc4a7f4bd0 (patch) | |
tree | bab256faae539cd38840bfc886317f80385acae4 /kernel | |
parent | 6f30558f37bfbd428e3854c2c34b5c32117c8f7e (diff) |
cgroup: remove cgroup->name
cgroup->name handling became quite complicated over time involving
dedicated struct cgroup_name for RCU protection. Now that cgroup is
on kernfs, we can drop all of it and simply use kernfs_name/path() and
friends. Replace cgroup->name and all related code with kernfs
name/path constructs.
* Reimplement cgroup_name() and cgroup_path() as thin wrappers on top
of kernfs counterparts, which involves semantic changes.
pr_cont_cgroup_name() and pr_cont_cgroup_path() added.
* cgroup->name handling dropped from cgroup_rename().
* All users of cgroup_name/path() updated to the new semantics. Users
which were formatting the string just to printk them are converted
to use pr_cont_cgroup_name/path() instead, which simplifies things
quite a bit. As cgroup_name() no longer requires RCU read lock
around it, RCU lockings which were protecting only cgroup_name() are
removed.
v2: Comment above oom_info_lock updated as suggested by Michal.
v3: dummy_top doesn't have a kn associated and
pr_cont_cgroup_name/path() ended up calling the matching kernfs
functions with NULL kn leading to oops. Test for NULL kn and
print "/" if so. This issue was reported by Fengguang Wu.
v4: Rebased on top of 0ab02ca8f887 ("cgroup: protect modifications to
cgroup_idr with cgroup_mutex").
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Acked-by: Michal Hocko <mhocko@suse.cz>
Acked-by: Li Zefan <lizefan@huawei.com>
Cc: Fengguang Wu <fengguang.wu@intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Balbir Singh <bsingharora@gmail.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/cgroup.c | 146 | ||||
-rw-r--r-- | kernel/cpuset.c | 27 | ||||
-rw-r--r-- | kernel/sched/debug.c | 3 |
3 files changed, 47 insertions, 129 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 59dfb025f1ac..638df032fb94 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -145,8 +145,6 @@ static int cgroup_root_count; | |||
145 | /* hierarchy ID allocation and mapping, protected by cgroup_mutex */ | 145 | /* hierarchy ID allocation and mapping, protected by cgroup_mutex */ |
146 | static DEFINE_IDR(cgroup_hierarchy_idr); | 146 | static DEFINE_IDR(cgroup_hierarchy_idr); |
147 | 147 | ||
148 | static struct cgroup_name root_cgroup_name = { .name = "/" }; | ||
149 | |||
150 | /* | 148 | /* |
151 | * Assign a monotonically increasing serial number to cgroups. It | 149 | * Assign a monotonically increasing serial number to cgroups. It |
152 | * guarantees cgroups with bigger numbers are newer than those with smaller | 150 | * guarantees cgroups with bigger numbers are newer than those with smaller |
@@ -888,17 +886,6 @@ static int cgroup_populate_dir(struct cgroup *cgrp, unsigned long subsys_mask); | |||
888 | static struct kernfs_syscall_ops cgroup_kf_syscall_ops; | 886 | static struct kernfs_syscall_ops cgroup_kf_syscall_ops; |
889 | static const struct file_operations proc_cgroupstats_operations; | 887 | static const struct file_operations proc_cgroupstats_operations; |
890 | 888 | ||
891 | static struct cgroup_name *cgroup_alloc_name(const char *name_str) | ||
892 | { | ||
893 | struct cgroup_name *name; | ||
894 | |||
895 | name = kmalloc(sizeof(*name) + strlen(name_str) + 1, GFP_KERNEL); | ||
896 | if (!name) | ||
897 | return NULL; | ||
898 | strcpy(name->name, name_str); | ||
899 | return name; | ||
900 | } | ||
901 | |||
902 | static char *cgroup_file_name(struct cgroup *cgrp, const struct cftype *cft, | 889 | static char *cgroup_file_name(struct cgroup *cgrp, const struct cftype *cft, |
903 | char *buf) | 890 | char *buf) |
904 | { | 891 | { |
@@ -958,8 +945,6 @@ static void cgroup_free_fn(struct work_struct *work) | |||
958 | cgroup_pidlist_destroy_all(cgrp); | 945 | cgroup_pidlist_destroy_all(cgrp); |
959 | 946 | ||
960 | kernfs_put(cgrp->kn); | 947 | kernfs_put(cgrp->kn); |
961 | |||
962 | kfree(rcu_dereference_raw(cgrp->name)); | ||
963 | kfree(cgrp); | 948 | kfree(cgrp); |
964 | } | 949 | } |
965 | 950 | ||
@@ -1377,7 +1362,6 @@ static void init_cgroup_root(struct cgroupfs_root *root) | |||
1377 | INIT_LIST_HEAD(&root->root_list); | 1362 | INIT_LIST_HEAD(&root->root_list); |
1378 | root->number_of_cgroups = 1; | 1363 | root->number_of_cgroups = 1; |
1379 | cgrp->root = root; | 1364 | cgrp->root = root; |
1380 | RCU_INIT_POINTER(cgrp->name, &root_cgroup_name); | ||
1381 | init_cgroup_housekeeping(cgrp); | 1365 | init_cgroup_housekeeping(cgrp); |
1382 | idr_init(&root->cgroup_idr); | 1366 | idr_init(&root->cgroup_idr); |
1383 | } | 1367 | } |
@@ -1598,57 +1582,6 @@ static struct file_system_type cgroup_fs_type = { | |||
1598 | static struct kobject *cgroup_kobj; | 1582 | static struct kobject *cgroup_kobj; |
1599 | 1583 | ||
1600 | /** | 1584 | /** |
1601 | * cgroup_path - generate the path of a cgroup | ||
1602 | * @cgrp: the cgroup in question | ||
1603 | * @buf: the buffer to write the path into | ||
1604 | * @buflen: the length of the buffer | ||
1605 | * | ||
1606 | * Writes path of cgroup into buf. Returns 0 on success, -errno on error. | ||
1607 | * | ||
1608 | * We can't generate cgroup path using dentry->d_name, as accessing | ||
1609 | * dentry->name must be protected by irq-unsafe dentry->d_lock or parent | ||
1610 | * inode's i_mutex, while on the other hand cgroup_path() can be called | ||
1611 | * with some irq-safe spinlocks held. | ||
1612 | */ | ||
1613 | int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen) | ||
1614 | { | ||
1615 | int ret = -ENAMETOOLONG; | ||
1616 | char *start; | ||
1617 | |||
1618 | if (!cgrp->parent) { | ||
1619 | if (strlcpy(buf, "/", buflen) >= buflen) | ||
1620 | return -ENAMETOOLONG; | ||
1621 | return 0; | ||
1622 | } | ||
1623 | |||
1624 | start = buf + buflen - 1; | ||
1625 | *start = '\0'; | ||
1626 | |||
1627 | rcu_read_lock(); | ||
1628 | do { | ||
1629 | const char *name = cgroup_name(cgrp); | ||
1630 | int len; | ||
1631 | |||
1632 | len = strlen(name); | ||
1633 | if ((start -= len) < buf) | ||
1634 | goto out; | ||
1635 | memcpy(start, name, len); | ||
1636 | |||
1637 | if (--start < buf) | ||
1638 | goto out; | ||
1639 | *start = '/'; | ||
1640 | |||
1641 | cgrp = cgrp->parent; | ||
1642 | } while (cgrp->parent); | ||
1643 | ret = 0; | ||
1644 | memmove(buf, start, buf + buflen - start); | ||
1645 | out: | ||
1646 | rcu_read_unlock(); | ||
1647 | return ret; | ||
1648 | } | ||
1649 | EXPORT_SYMBOL_GPL(cgroup_path); | ||
1650 | |||
1651 | /** | ||
1652 | * task_cgroup_path - cgroup path of a task in the first cgroup hierarchy | 1585 | * task_cgroup_path - cgroup path of a task in the first cgroup hierarchy |
1653 | * @task: target task | 1586 | * @task: target task |
1654 | * @buf: the buffer to write the path into | 1587 | * @buf: the buffer to write the path into |
@@ -1659,16 +1592,14 @@ EXPORT_SYMBOL_GPL(cgroup_path); | |||
1659 | * function grabs cgroup_mutex and shouldn't be used inside locks used by | 1592 | * function grabs cgroup_mutex and shouldn't be used inside locks used by |
1660 | * cgroup controller callbacks. | 1593 | * cgroup controller callbacks. |
1661 | * | 1594 | * |
1662 | * Returns 0 on success, fails with -%ENAMETOOLONG if @buflen is too short. | 1595 | * Return value is the same as kernfs_path(). |
1663 | */ | 1596 | */ |
1664 | int task_cgroup_path(struct task_struct *task, char *buf, size_t buflen) | 1597 | char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen) |
1665 | { | 1598 | { |
1666 | struct cgroupfs_root *root; | 1599 | struct cgroupfs_root *root; |
1667 | struct cgroup *cgrp; | 1600 | struct cgroup *cgrp; |
1668 | int hierarchy_id = 1, ret = 0; | 1601 | int hierarchy_id = 1; |
1669 | 1602 | char *path = NULL; | |
1670 | if (buflen < 2) | ||
1671 | return -ENAMETOOLONG; | ||
1672 | 1603 | ||
1673 | mutex_lock(&cgroup_mutex); | 1604 | mutex_lock(&cgroup_mutex); |
1674 | 1605 | ||
@@ -1676,14 +1607,15 @@ int task_cgroup_path(struct task_struct *task, char *buf, size_t buflen) | |||
1676 | 1607 | ||
1677 | if (root) { | 1608 | if (root) { |
1678 | cgrp = task_cgroup_from_root(task, root); | 1609 | cgrp = task_cgroup_from_root(task, root); |
1679 | ret = cgroup_path(cgrp, buf, buflen); | 1610 | path = cgroup_path(cgrp, buf, buflen); |
1680 | } else { | 1611 | } else { |
1681 | /* if no hierarchy exists, everyone is in "/" */ | 1612 | /* if no hierarchy exists, everyone is in "/" */ |
1682 | memcpy(buf, "/", 2); | 1613 | if (strlcpy(buf, "/", buflen) < buflen) |
1614 | path = buf; | ||
1683 | } | 1615 | } |
1684 | 1616 | ||
1685 | mutex_unlock(&cgroup_mutex); | 1617 | mutex_unlock(&cgroup_mutex); |
1686 | return ret; | 1618 | return path; |
1687 | } | 1619 | } |
1688 | EXPORT_SYMBOL_GPL(task_cgroup_path); | 1620 | EXPORT_SYMBOL_GPL(task_cgroup_path); |
1689 | 1621 | ||
@@ -2211,7 +2143,6 @@ static int cgroup_rename(struct kernfs_node *kn, struct kernfs_node *new_parent, | |||
2211 | const char *new_name_str) | 2143 | const char *new_name_str) |
2212 | { | 2144 | { |
2213 | struct cgroup *cgrp = kn->priv; | 2145 | struct cgroup *cgrp = kn->priv; |
2214 | struct cgroup_name *name, *old_name; | ||
2215 | int ret; | 2146 | int ret; |
2216 | 2147 | ||
2217 | if (kernfs_type(kn) != KERNFS_DIR) | 2148 | if (kernfs_type(kn) != KERNFS_DIR) |
@@ -2226,25 +2157,13 @@ static int cgroup_rename(struct kernfs_node *kn, struct kernfs_node *new_parent, | |||
2226 | if (cgroup_sane_behavior(cgrp)) | 2157 | if (cgroup_sane_behavior(cgrp)) |
2227 | return -EPERM; | 2158 | return -EPERM; |
2228 | 2159 | ||
2229 | name = cgroup_alloc_name(new_name_str); | ||
2230 | if (!name) | ||
2231 | return -ENOMEM; | ||
2232 | |||
2233 | mutex_lock(&cgroup_tree_mutex); | 2160 | mutex_lock(&cgroup_tree_mutex); |
2234 | mutex_lock(&cgroup_mutex); | 2161 | mutex_lock(&cgroup_mutex); |
2235 | 2162 | ||
2236 | ret = kernfs_rename(kn, new_parent, new_name_str); | 2163 | ret = kernfs_rename(kn, new_parent, new_name_str); |
2237 | if (!ret) { | ||
2238 | old_name = rcu_dereference_protected(cgrp->name, true); | ||
2239 | rcu_assign_pointer(cgrp->name, name); | ||
2240 | } else { | ||
2241 | old_name = name; | ||
2242 | } | ||
2243 | 2164 | ||
2244 | mutex_unlock(&cgroup_mutex); | 2165 | mutex_unlock(&cgroup_mutex); |
2245 | mutex_unlock(&cgroup_tree_mutex); | 2166 | mutex_unlock(&cgroup_tree_mutex); |
2246 | |||
2247 | kfree_rcu(old_name, rcu_head); | ||
2248 | return ret; | 2167 | return ret; |
2249 | } | 2168 | } |
2250 | 2169 | ||
@@ -3719,14 +3638,13 @@ err_free: | |||
3719 | /** | 3638 | /** |
3720 | * cgroup_create - create a cgroup | 3639 | * cgroup_create - create a cgroup |
3721 | * @parent: cgroup that will be parent of the new cgroup | 3640 | * @parent: cgroup that will be parent of the new cgroup |
3722 | * @name_str: name of the new cgroup | 3641 | * @name: name of the new cgroup |
3723 | * @mode: mode to set on new cgroup | 3642 | * @mode: mode to set on new cgroup |
3724 | */ | 3643 | */ |
3725 | static long cgroup_create(struct cgroup *parent, const char *name_str, | 3644 | static long cgroup_create(struct cgroup *parent, const char *name, |
3726 | umode_t mode) | 3645 | umode_t mode) |
3727 | { | 3646 | { |
3728 | struct cgroup *cgrp; | 3647 | struct cgroup *cgrp; |
3729 | struct cgroup_name *name; | ||
3730 | struct cgroupfs_root *root = parent->root; | 3648 | struct cgroupfs_root *root = parent->root; |
3731 | int ssid, err; | 3649 | int ssid, err; |
3732 | struct cgroup_subsys *ss; | 3650 | struct cgroup_subsys *ss; |
@@ -3737,13 +3655,6 @@ static long cgroup_create(struct cgroup *parent, const char *name_str, | |||
3737 | if (!cgrp) | 3655 | if (!cgrp) |
3738 | return -ENOMEM; | 3656 | return -ENOMEM; |
3739 | 3657 | ||
3740 | name = cgroup_alloc_name(name_str); | ||
3741 | if (!name) { | ||
3742 | err = -ENOMEM; | ||
3743 | goto err_free_cgrp; | ||
3744 | } | ||
3745 | rcu_assign_pointer(cgrp->name, name); | ||
3746 | |||
3747 | mutex_lock(&cgroup_tree_mutex); | 3658 | mutex_lock(&cgroup_tree_mutex); |
3748 | 3659 | ||
3749 | /* | 3660 | /* |
@@ -3781,7 +3692,7 @@ static long cgroup_create(struct cgroup *parent, const char *name_str, | |||
3781 | set_bit(CGRP_CPUSET_CLONE_CHILDREN, &cgrp->flags); | 3692 | set_bit(CGRP_CPUSET_CLONE_CHILDREN, &cgrp->flags); |
3782 | 3693 | ||
3783 | /* create the directory */ | 3694 | /* create the directory */ |
3784 | kn = kernfs_create_dir(parent->kn, name->name, mode, cgrp); | 3695 | kn = kernfs_create_dir(parent->kn, name, mode, cgrp); |
3785 | if (IS_ERR(kn)) { | 3696 | if (IS_ERR(kn)) { |
3786 | err = PTR_ERR(kn); | 3697 | err = PTR_ERR(kn); |
3787 | goto err_free_id; | 3698 | goto err_free_id; |
@@ -3839,8 +3750,6 @@ err_unlock: | |||
3839 | mutex_unlock(&cgroup_mutex); | 3750 | mutex_unlock(&cgroup_mutex); |
3840 | err_unlock_tree: | 3751 | err_unlock_tree: |
3841 | mutex_unlock(&cgroup_tree_mutex); | 3752 | mutex_unlock(&cgroup_tree_mutex); |
3842 | kfree(rcu_dereference_raw(cgrp->name)); | ||
3843 | err_free_cgrp: | ||
3844 | kfree(cgrp); | 3753 | kfree(cgrp); |
3845 | return err; | 3754 | return err; |
3846 | 3755 | ||
@@ -4304,12 +4213,12 @@ int proc_cgroup_show(struct seq_file *m, void *v) | |||
4304 | { | 4213 | { |
4305 | struct pid *pid; | 4214 | struct pid *pid; |
4306 | struct task_struct *tsk; | 4215 | struct task_struct *tsk; |
4307 | char *buf; | 4216 | char *buf, *path; |
4308 | int retval; | 4217 | int retval; |
4309 | struct cgroupfs_root *root; | 4218 | struct cgroupfs_root *root; |
4310 | 4219 | ||
4311 | retval = -ENOMEM; | 4220 | retval = -ENOMEM; |
4312 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | 4221 | buf = kmalloc(PATH_MAX, GFP_KERNEL); |
4313 | if (!buf) | 4222 | if (!buf) |
4314 | goto out; | 4223 | goto out; |
4315 | 4224 | ||
@@ -4337,10 +4246,12 @@ int proc_cgroup_show(struct seq_file *m, void *v) | |||
4337 | root->name); | 4246 | root->name); |
4338 | seq_putc(m, ':'); | 4247 | seq_putc(m, ':'); |
4339 | cgrp = task_cgroup_from_root(tsk, root); | 4248 | cgrp = task_cgroup_from_root(tsk, root); |
4340 | retval = cgroup_path(cgrp, buf, PAGE_SIZE); | 4249 | path = cgroup_path(cgrp, buf, PATH_MAX); |
4341 | if (retval < 0) | 4250 | if (!path) { |
4251 | retval = -ENAMETOOLONG; | ||
4342 | goto out_unlock; | 4252 | goto out_unlock; |
4343 | seq_puts(m, buf); | 4253 | } |
4254 | seq_puts(m, path); | ||
4344 | seq_putc(m, '\n'); | 4255 | seq_putc(m, '\n'); |
4345 | } | 4256 | } |
4346 | 4257 | ||
@@ -4588,16 +4499,17 @@ static void cgroup_release_agent(struct work_struct *work) | |||
4588 | while (!list_empty(&release_list)) { | 4499 | while (!list_empty(&release_list)) { |
4589 | char *argv[3], *envp[3]; | 4500 | char *argv[3], *envp[3]; |
4590 | int i; | 4501 | int i; |
4591 | char *pathbuf = NULL, *agentbuf = NULL; | 4502 | char *pathbuf = NULL, *agentbuf = NULL, *path; |
4592 | struct cgroup *cgrp = list_entry(release_list.next, | 4503 | struct cgroup *cgrp = list_entry(release_list.next, |
4593 | struct cgroup, | 4504 | struct cgroup, |
4594 | release_list); | 4505 | release_list); |
4595 | list_del_init(&cgrp->release_list); | 4506 | list_del_init(&cgrp->release_list); |
4596 | raw_spin_unlock(&release_list_lock); | 4507 | raw_spin_unlock(&release_list_lock); |
4597 | pathbuf = kmalloc(PAGE_SIZE, GFP_KERNEL); | 4508 | pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); |
4598 | if (!pathbuf) | 4509 | if (!pathbuf) |
4599 | goto continue_free; | 4510 | goto continue_free; |
4600 | if (cgroup_path(cgrp, pathbuf, PAGE_SIZE) < 0) | 4511 | path = cgroup_path(cgrp, pathbuf, PATH_MAX); |
4512 | if (!path) | ||
4601 | goto continue_free; | 4513 | goto continue_free; |
4602 | agentbuf = kstrdup(cgrp->root->release_agent_path, GFP_KERNEL); | 4514 | agentbuf = kstrdup(cgrp->root->release_agent_path, GFP_KERNEL); |
4603 | if (!agentbuf) | 4515 | if (!agentbuf) |
@@ -4605,7 +4517,7 @@ static void cgroup_release_agent(struct work_struct *work) | |||
4605 | 4517 | ||
4606 | i = 0; | 4518 | i = 0; |
4607 | argv[i++] = agentbuf; | 4519 | argv[i++] = agentbuf; |
4608 | argv[i++] = pathbuf; | 4520 | argv[i++] = path; |
4609 | argv[i] = NULL; | 4521 | argv[i] = NULL; |
4610 | 4522 | ||
4611 | i = 0; | 4523 | i = 0; |
@@ -4755,6 +4667,11 @@ static int current_css_set_cg_links_read(struct seq_file *seq, void *v) | |||
4755 | { | 4667 | { |
4756 | struct cgrp_cset_link *link; | 4668 | struct cgrp_cset_link *link; |
4757 | struct css_set *cset; | 4669 | struct css_set *cset; |
4670 | char *name_buf; | ||
4671 | |||
4672 | name_buf = kmalloc(NAME_MAX + 1, GFP_KERNEL); | ||
4673 | if (!name_buf) | ||
4674 | return -ENOMEM; | ||
4758 | 4675 | ||
4759 | read_lock(&css_set_lock); | 4676 | read_lock(&css_set_lock); |
4760 | rcu_read_lock(); | 4677 | rcu_read_lock(); |
@@ -4763,14 +4680,17 @@ static int current_css_set_cg_links_read(struct seq_file *seq, void *v) | |||
4763 | struct cgroup *c = link->cgrp; | 4680 | struct cgroup *c = link->cgrp; |
4764 | const char *name = "?"; | 4681 | const char *name = "?"; |
4765 | 4682 | ||
4766 | if (c != cgroup_dummy_top) | 4683 | if (c != cgroup_dummy_top) { |
4767 | name = cgroup_name(c); | 4684 | cgroup_name(c, name_buf, NAME_MAX + 1); |
4685 | name = name_buf; | ||
4686 | } | ||
4768 | 4687 | ||
4769 | seq_printf(seq, "Root %d group %s\n", | 4688 | seq_printf(seq, "Root %d group %s\n", |
4770 | c->root->hierarchy_id, name); | 4689 | c->root->hierarchy_id, name); |
4771 | } | 4690 | } |
4772 | rcu_read_unlock(); | 4691 | rcu_read_unlock(); |
4773 | read_unlock(&css_set_lock); | 4692 | read_unlock(&css_set_lock); |
4693 | kfree(name_buf); | ||
4774 | return 0; | 4694 | return 0; |
4775 | } | 4695 | } |
4776 | 4696 | ||
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 2d018c795fea..e97a6e88d036 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -2088,10 +2088,9 @@ static void remove_tasks_in_empty_cpuset(struct cpuset *cs) | |||
2088 | parent = parent_cs(parent); | 2088 | parent = parent_cs(parent); |
2089 | 2089 | ||
2090 | if (cgroup_transfer_tasks(parent->css.cgroup, cs->css.cgroup)) { | 2090 | if (cgroup_transfer_tasks(parent->css.cgroup, cs->css.cgroup)) { |
2091 | rcu_read_lock(); | 2091 | printk(KERN_ERR "cpuset: failed to transfer tasks out of empty cpuset "); |
2092 | printk(KERN_ERR "cpuset: failed to transfer tasks out of empty cpuset %s\n", | 2092 | pr_cont_cgroup_name(cs->css.cgroup); |
2093 | cgroup_name(cs->css.cgroup)); | 2093 | pr_cont("\n"); |
2094 | rcu_read_unlock(); | ||
2095 | } | 2094 | } |
2096 | } | 2095 | } |
2097 | 2096 | ||
@@ -2619,19 +2618,17 @@ void cpuset_print_task_mems_allowed(struct task_struct *tsk) | |||
2619 | /* Statically allocated to prevent using excess stack. */ | 2618 | /* Statically allocated to prevent using excess stack. */ |
2620 | static char cpuset_nodelist[CPUSET_NODELIST_LEN]; | 2619 | static char cpuset_nodelist[CPUSET_NODELIST_LEN]; |
2621 | static DEFINE_SPINLOCK(cpuset_buffer_lock); | 2620 | static DEFINE_SPINLOCK(cpuset_buffer_lock); |
2622 | |||
2623 | struct cgroup *cgrp = task_cs(tsk)->css.cgroup; | 2621 | struct cgroup *cgrp = task_cs(tsk)->css.cgroup; |
2624 | 2622 | ||
2625 | rcu_read_lock(); | ||
2626 | spin_lock(&cpuset_buffer_lock); | 2623 | spin_lock(&cpuset_buffer_lock); |
2627 | 2624 | ||
2628 | nodelist_scnprintf(cpuset_nodelist, CPUSET_NODELIST_LEN, | 2625 | nodelist_scnprintf(cpuset_nodelist, CPUSET_NODELIST_LEN, |
2629 | tsk->mems_allowed); | 2626 | tsk->mems_allowed); |
2630 | printk(KERN_INFO "%s cpuset=%s mems_allowed=%s\n", | 2627 | printk(KERN_INFO "%s cpuset=", tsk->comm); |
2631 | tsk->comm, cgroup_name(cgrp), cpuset_nodelist); | 2628 | pr_cont_cgroup_name(cgrp); |
2629 | pr_cont(" mems_allowed=%s\n", cpuset_nodelist); | ||
2632 | 2630 | ||
2633 | spin_unlock(&cpuset_buffer_lock); | 2631 | spin_unlock(&cpuset_buffer_lock); |
2634 | rcu_read_unlock(); | ||
2635 | } | 2632 | } |
2636 | 2633 | ||
2637 | /* | 2634 | /* |
@@ -2681,12 +2678,12 @@ int proc_cpuset_show(struct seq_file *m, void *unused_v) | |||
2681 | { | 2678 | { |
2682 | struct pid *pid; | 2679 | struct pid *pid; |
2683 | struct task_struct *tsk; | 2680 | struct task_struct *tsk; |
2684 | char *buf; | 2681 | char *buf, *p; |
2685 | struct cgroup_subsys_state *css; | 2682 | struct cgroup_subsys_state *css; |
2686 | int retval; | 2683 | int retval; |
2687 | 2684 | ||
2688 | retval = -ENOMEM; | 2685 | retval = -ENOMEM; |
2689 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | 2686 | buf = kmalloc(PATH_MAX, GFP_KERNEL); |
2690 | if (!buf) | 2687 | if (!buf) |
2691 | goto out; | 2688 | goto out; |
2692 | 2689 | ||
@@ -2696,14 +2693,16 @@ int proc_cpuset_show(struct seq_file *m, void *unused_v) | |||
2696 | if (!tsk) | 2693 | if (!tsk) |
2697 | goto out_free; | 2694 | goto out_free; |
2698 | 2695 | ||
2696 | retval = -ENAMETOOLONG; | ||
2699 | rcu_read_lock(); | 2697 | rcu_read_lock(); |
2700 | css = task_css(tsk, cpuset_cgrp_id); | 2698 | css = task_css(tsk, cpuset_cgrp_id); |
2701 | retval = cgroup_path(css->cgroup, buf, PAGE_SIZE); | 2699 | p = cgroup_path(css->cgroup, buf, PATH_MAX); |
2702 | rcu_read_unlock(); | 2700 | rcu_read_unlock(); |
2703 | if (retval < 0) | 2701 | if (!p) |
2704 | goto out_put_task; | 2702 | goto out_put_task; |
2705 | seq_puts(m, buf); | 2703 | seq_puts(m, p); |
2706 | seq_putc(m, '\n'); | 2704 | seq_putc(m, '\n'); |
2705 | retval = 0; | ||
2707 | out_put_task: | 2706 | out_put_task: |
2708 | put_task_struct(tsk); | 2707 | put_task_struct(tsk); |
2709 | out_free: | 2708 | out_free: |
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index dd52e7ffb10e..30eee3b5293d 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c | |||
@@ -111,8 +111,7 @@ static char *task_group_path(struct task_group *tg) | |||
111 | if (autogroup_path(tg, group_path, PATH_MAX)) | 111 | if (autogroup_path(tg, group_path, PATH_MAX)) |
112 | return group_path; | 112 | return group_path; |
113 | 113 | ||
114 | cgroup_path(tg->css.cgroup, group_path, PATH_MAX); | 114 | return cgroup_path(tg->css.cgroup, group_path, PATH_MAX); |
115 | return group_path; | ||
116 | } | 115 | } |
117 | #endif | 116 | #endif |
118 | 117 | ||