aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-14 15:18:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-14 15:18:50 -0400
commitf34d3606f76a8121b9d4940d2dd436bebeb2f9d7 (patch)
tree61a9deb6a950568df274580fbbd44a7015af9f7c
parentb6daa51b9a6a02a644dcf6b880fd50c1f70ec07f (diff)
parentbbb427e342495df1cda10051d0566388697499c0 (diff)
Merge branch 'for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup updates from Tejun Heo: - tracepoints for basic cgroup management operations added - kernfs and cgroup path formatting functions updated to behave in the style of strlcpy() - non-critical bug fixes * 'for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: blkcg: Unlock blkcg_pol_mutex only once when cpd == NULL cgroup: fix error handling regressions in proc_cgroup_show() and cgroup_release_agent() cpuset: fix error handling regression in proc_cpuset_show() cgroup: add tracepoints for basic operations cgroup: make cgroup_path() and friends behave in the style of strlcpy() kernfs: remove kernfs_path_len() kernfs: make kernfs_path*() behave in the style of strlcpy() kernfs: add dummy implementation of kernfs_path_from_node()
-rw-r--r--block/blk-cgroup.c4
-rw-r--r--fs/kernfs/dir.c84
-rw-r--r--fs/sysfs/dir.c6
-rw-r--r--include/linux/blk-cgroup.h11
-rw-r--r--include/linux/cgroup.h9
-rw-r--r--include/linux/kernfs.h28
-rw-r--r--include/trace/events/cgroup.h163
-rw-r--r--kernel/cgroup.c75
-rw-r--r--kernel/cpuset.c13
-rw-r--r--kernel/sched/debug.c3
10 files changed, 266 insertions, 130 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index dd38e5ced4a3..b08ccbb9393a 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -1340,10 +1340,8 @@ int blkcg_policy_register(struct blkcg_policy *pol)
1340 struct blkcg_policy_data *cpd; 1340 struct blkcg_policy_data *cpd;
1341 1341
1342 cpd = pol->cpd_alloc_fn(GFP_KERNEL); 1342 cpd = pol->cpd_alloc_fn(GFP_KERNEL);
1343 if (!cpd) { 1343 if (!cpd)
1344 mutex_unlock(&blkcg_pol_mutex);
1345 goto err_free_cpds; 1344 goto err_free_cpds;
1346 }
1347 1345
1348 blkcg->cpd[pol->plid] = cpd; 1346 blkcg->cpd[pol->plid] = cpd;
1349 cpd->blkcg = blkcg; 1347 cpd->blkcg = blkcg;
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index dcd96aac02f5..cf4c636ff4da 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -110,8 +110,9 @@ static struct kernfs_node *kernfs_common_ancestor(struct kernfs_node *a,
110 * kn_to: /n1/n2/n3 [depth=3] 110 * kn_to: /n1/n2/n3 [depth=3]
111 * result: /../.. 111 * result: /../..
112 * 112 *
113 * return value: length of the string. If greater than buflen, 113 * Returns the length of the full path. If the full length is equal to or
114 * then contents of buf are undefined. On error, -1 is returned. 114 * greater than @buflen, @buf contains the truncated path with the trailing
115 * '\0'. On error, -errno is returned.
115 */ 116 */
116static int kernfs_path_from_node_locked(struct kernfs_node *kn_to, 117static int kernfs_path_from_node_locked(struct kernfs_node *kn_to,
117 struct kernfs_node *kn_from, 118 struct kernfs_node *kn_from,
@@ -119,9 +120,8 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to,
119{ 120{
120 struct kernfs_node *kn, *common; 121 struct kernfs_node *kn, *common;
121 const char parent_str[] = "/.."; 122 const char parent_str[] = "/..";
122 size_t depth_from, depth_to, len = 0, nlen = 0; 123 size_t depth_from, depth_to, len = 0;
123 char *p; 124 int i, j;
124 int i;
125 125
126 if (!kn_from) 126 if (!kn_from)
127 kn_from = kernfs_root(kn_to)->kn; 127 kn_from = kernfs_root(kn_to)->kn;
@@ -131,7 +131,7 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to,
131 131
132 common = kernfs_common_ancestor(kn_from, kn_to); 132 common = kernfs_common_ancestor(kn_from, kn_to);
133 if (WARN_ON(!common)) 133 if (WARN_ON(!common))
134 return -1; 134 return -EINVAL;
135 135
136 depth_to = kernfs_depth(common, kn_to); 136 depth_to = kernfs_depth(common, kn_to);
137 depth_from = kernfs_depth(common, kn_from); 137 depth_from = kernfs_depth(common, kn_from);
@@ -144,22 +144,16 @@ static int kernfs_path_from_node_locked(struct kernfs_node *kn_to,
144 len < buflen ? buflen - len : 0); 144 len < buflen ? buflen - len : 0);
145 145
146 /* Calculate how many bytes we need for the rest */ 146 /* Calculate how many bytes we need for the rest */
147 for (kn = kn_to; kn != common; kn = kn->parent) 147 for (i = depth_to - 1; i >= 0; i--) {
148 nlen += strlen(kn->name) + 1; 148 for (kn = kn_to, j = 0; j < i; j++)
149 149 kn = kn->parent;
150 if (len + nlen >= buflen) 150 len += strlcpy(buf + len, "/",
151 return len + nlen; 151 len < buflen ? buflen - len : 0);
152 152 len += strlcpy(buf + len, kn->name,
153 p = buf + len + nlen; 153 len < buflen ? buflen - len : 0);
154 *p = '\0';
155 for (kn = kn_to; kn != common; kn = kn->parent) {
156 size_t tmp = strlen(kn->name);
157 p -= tmp;
158 memcpy(p, kn->name, tmp);
159 *(--p) = '/';
160 } 154 }
161 155
162 return len + nlen; 156 return len;
163} 157}
164 158
165/** 159/**
@@ -186,29 +180,6 @@ int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen)
186} 180}
187 181
188/** 182/**
189 * kernfs_path_len - determine the length of the full path of a given node
190 * @kn: kernfs_node of interest
191 *
192 * The returned length doesn't include the space for the terminating '\0'.
193 */
194size_t kernfs_path_len(struct kernfs_node *kn)
195{
196 size_t len = 0;
197 unsigned long flags;
198
199 spin_lock_irqsave(&kernfs_rename_lock, flags);
200
201 do {
202 len += strlen(kn->name) + 1;
203 kn = kn->parent;
204 } while (kn && kn->parent);
205
206 spin_unlock_irqrestore(&kernfs_rename_lock, flags);
207
208 return len;
209}
210
211/**
212 * kernfs_path_from_node - build path of node @to relative to @from. 183 * kernfs_path_from_node - build path of node @to relative to @from.
213 * @from: parent kernfs_node relative to which we need to build the path 184 * @from: parent kernfs_node relative to which we need to build the path
214 * @to: kernfs_node of interest 185 * @to: kernfs_node of interest
@@ -220,8 +191,9 @@ size_t kernfs_path_len(struct kernfs_node *kn)
220 * path (which includes '..'s) as needed to reach from @from to @to is 191 * path (which includes '..'s) as needed to reach from @from to @to is
221 * returned. 192 * returned.
222 * 193 *
223 * If @buf isn't long enough, the return value will be greater than @buflen 194 * Returns the length of the full path. If the full length is equal to or
224 * and @buf contents are undefined. 195 * greater than @buflen, @buf contains the truncated path with the trailing
196 * '\0'. On error, -errno is returned.
225 */ 197 */
226int kernfs_path_from_node(struct kernfs_node *to, struct kernfs_node *from, 198int kernfs_path_from_node(struct kernfs_node *to, struct kernfs_node *from,
227 char *buf, size_t buflen) 199 char *buf, size_t buflen)
@@ -237,28 +209,6 @@ int kernfs_path_from_node(struct kernfs_node *to, struct kernfs_node *from,
237EXPORT_SYMBOL_GPL(kernfs_path_from_node); 209EXPORT_SYMBOL_GPL(kernfs_path_from_node);
238 210
239/** 211/**
240 * kernfs_path - build full path of a given node
241 * @kn: kernfs_node of interest
242 * @buf: buffer to copy @kn's name into
243 * @buflen: size of @buf
244 *
245 * Builds and returns the full path of @kn in @buf of @buflen bytes. The
246 * path is built from the end of @buf so the returned pointer usually
247 * doesn't match @buf. If @buf isn't long enough, @buf is nul terminated
248 * and %NULL is returned.
249 */
250char *kernfs_path(struct kernfs_node *kn, char *buf, size_t buflen)
251{
252 int ret;
253
254 ret = kernfs_path_from_node(kn, NULL, buf, buflen);
255 if (ret < 0 || ret >= buflen)
256 return NULL;
257 return buf;
258}
259EXPORT_SYMBOL_GPL(kernfs_path);
260
261/**
262 * pr_cont_kernfs_name - pr_cont name of a kernfs_node 212 * pr_cont_kernfs_name - pr_cont name of a kernfs_node
263 * @kn: kernfs_node of interest 213 * @kn: kernfs_node of interest
264 * 214 *
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 94374e435025..2b67bda2021b 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -21,14 +21,14 @@ DEFINE_SPINLOCK(sysfs_symlink_target_lock);
21 21
22void sysfs_warn_dup(struct kernfs_node *parent, const char *name) 22void sysfs_warn_dup(struct kernfs_node *parent, const char *name)
23{ 23{
24 char *buf, *path = NULL; 24 char *buf;
25 25
26 buf = kzalloc(PATH_MAX, GFP_KERNEL); 26 buf = kzalloc(PATH_MAX, GFP_KERNEL);
27 if (buf) 27 if (buf)
28 path = kernfs_path(parent, buf, PATH_MAX); 28 kernfs_path(parent, buf, PATH_MAX);
29 29
30 WARN(1, KERN_WARNING "sysfs: cannot create duplicate filename '%s/%s'\n", 30 WARN(1, KERN_WARNING "sysfs: cannot create duplicate filename '%s/%s'\n",
31 path, name); 31 buf, name);
32 32
33 kfree(buf); 33 kfree(buf);
34} 34}
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index cbdbf34de5b6..3bf5d33800ab 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -343,16 +343,7 @@ static inline struct blkcg *cpd_to_blkcg(struct blkcg_policy_data *cpd)
343 */ 343 */
344static inline int blkg_path(struct blkcg_gq *blkg, char *buf, int buflen) 344static inline int blkg_path(struct blkcg_gq *blkg, char *buf, int buflen)
345{ 345{
346 char *p; 346 return cgroup_path(blkg->blkcg->css.cgroup, buf, buflen);
347
348 p = cgroup_path(blkg->blkcg->css.cgroup, buf, buflen);
349 if (!p) {
350 strncpy(buf, "<unavailable>", buflen);
351 return -ENAMETOOLONG;
352 }
353
354 memmove(buf, p, buf + buflen - p);
355 return 0;
356} 347}
357 348
358/** 349/**
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 440a72164a11..c83c23f0577b 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -97,7 +97,7 @@ int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
97int cgroup_rm_cftypes(struct cftype *cfts); 97int cgroup_rm_cftypes(struct cftype *cfts);
98void cgroup_file_notify(struct cgroup_file *cfile); 98void cgroup_file_notify(struct cgroup_file *cfile);
99 99
100char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen); 100int task_cgroup_path(struct task_struct *task, char *buf, size_t buflen);
101int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry); 101int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry);
102int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns, 102int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
103 struct pid *pid, struct task_struct *tsk); 103 struct pid *pid, struct task_struct *tsk);
@@ -555,8 +555,7 @@ static inline int cgroup_name(struct cgroup *cgrp, char *buf, size_t buflen)
555 return kernfs_name(cgrp->kn, buf, buflen); 555 return kernfs_name(cgrp->kn, buf, buflen);
556} 556}
557 557
558static inline char * __must_check cgroup_path(struct cgroup *cgrp, char *buf, 558static inline int cgroup_path(struct cgroup *cgrp, char *buf, size_t buflen)
559 size_t buflen)
560{ 559{
561 return kernfs_path(cgrp->kn, buf, buflen); 560 return kernfs_path(cgrp->kn, buf, buflen);
562} 561}
@@ -658,8 +657,8 @@ struct cgroup_namespace *copy_cgroup_ns(unsigned long flags,
658 struct user_namespace *user_ns, 657 struct user_namespace *user_ns,
659 struct cgroup_namespace *old_ns); 658 struct cgroup_namespace *old_ns);
660 659
661char *cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen, 660int cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen,
662 struct cgroup_namespace *ns); 661 struct cgroup_namespace *ns);
663 662
664#else /* !CONFIG_CGROUPS */ 663#else /* !CONFIG_CGROUPS */
665 664
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 96356ef012de..7056238fd9f5 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -269,10 +269,8 @@ static inline bool kernfs_ns_enabled(struct kernfs_node *kn)
269} 269}
270 270
271int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen); 271int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen);
272size_t kernfs_path_len(struct kernfs_node *kn);
273int kernfs_path_from_node(struct kernfs_node *root_kn, struct kernfs_node *kn, 272int kernfs_path_from_node(struct kernfs_node *root_kn, struct kernfs_node *kn,
274 char *buf, size_t buflen); 273 char *buf, size_t buflen);
275char *kernfs_path(struct kernfs_node *kn, char *buf, size_t buflen);
276void pr_cont_kernfs_name(struct kernfs_node *kn); 274void pr_cont_kernfs_name(struct kernfs_node *kn);
277void pr_cont_kernfs_path(struct kernfs_node *kn); 275void pr_cont_kernfs_path(struct kernfs_node *kn);
278struct kernfs_node *kernfs_get_parent(struct kernfs_node *kn); 276struct kernfs_node *kernfs_get_parent(struct kernfs_node *kn);
@@ -341,12 +339,10 @@ static inline bool kernfs_ns_enabled(struct kernfs_node *kn)
341static inline int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen) 339static inline int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen)
342{ return -ENOSYS; } 340{ return -ENOSYS; }
343 341
344static inline size_t kernfs_path_len(struct kernfs_node *kn) 342static inline int kernfs_path_from_node(struct kernfs_node *root_kn,
345{ return 0; } 343 struct kernfs_node *kn,
346 344 char *buf, size_t buflen)
347static inline char *kernfs_path(struct kernfs_node *kn, char *buf, 345{ return -ENOSYS; }
348 size_t buflen)
349{ return NULL; }
350 346
351static inline void pr_cont_kernfs_name(struct kernfs_node *kn) { } 347static inline void pr_cont_kernfs_name(struct kernfs_node *kn) { }
352static inline void pr_cont_kernfs_path(struct kernfs_node *kn) { } 348static inline void pr_cont_kernfs_path(struct kernfs_node *kn) { }
@@ -436,6 +432,22 @@ static inline void kernfs_init(void) { }
436 432
437#endif /* CONFIG_KERNFS */ 433#endif /* CONFIG_KERNFS */
438 434
435/**
436 * kernfs_path - build full path of a given node
437 * @kn: kernfs_node of interest
438 * @buf: buffer to copy @kn's name into
439 * @buflen: size of @buf
440 *
441 * Builds and returns the full path of @kn in @buf of @buflen bytes. The
442 * path is built from the end of @buf so the returned pointer usually
443 * doesn't match @buf. If @buf isn't long enough, @buf is nul terminated
444 * and %NULL is returned.
445 */
446static inline int kernfs_path(struct kernfs_node *kn, char *buf, size_t buflen)
447{
448 return kernfs_path_from_node(kn, NULL, buf, buflen);
449}
450
439static inline struct kernfs_node * 451static inline struct kernfs_node *
440kernfs_find_and_get(struct kernfs_node *kn, const char *name) 452kernfs_find_and_get(struct kernfs_node *kn, const char *name)
441{ 453{
diff --git a/include/trace/events/cgroup.h b/include/trace/events/cgroup.h
new file mode 100644
index 000000000000..ab68640a18d0
--- /dev/null
+++ b/include/trace/events/cgroup.h
@@ -0,0 +1,163 @@
1#undef TRACE_SYSTEM
2#define TRACE_SYSTEM cgroup
3
4#if !defined(_TRACE_CGROUP_H) || defined(TRACE_HEADER_MULTI_READ)
5#define _TRACE_CGROUP_H
6
7#include <linux/cgroup.h>
8#include <linux/tracepoint.h>
9
10DECLARE_EVENT_CLASS(cgroup_root,
11
12 TP_PROTO(struct cgroup_root *root),
13
14 TP_ARGS(root),
15
16 TP_STRUCT__entry(
17 __field( int, root )
18 __field( u16, ss_mask )
19 __string( name, root->name )
20 ),
21
22 TP_fast_assign(
23 __entry->root = root->hierarchy_id;
24 __entry->ss_mask = root->subsys_mask;
25 __assign_str(name, root->name);
26 ),
27
28 TP_printk("root=%d ss_mask=%#x name=%s",
29 __entry->root, __entry->ss_mask, __get_str(name))
30);
31
32DEFINE_EVENT(cgroup_root, cgroup_setup_root,
33
34 TP_PROTO(struct cgroup_root *root),
35
36 TP_ARGS(root)
37);
38
39DEFINE_EVENT(cgroup_root, cgroup_destroy_root,
40
41 TP_PROTO(struct cgroup_root *root),
42
43 TP_ARGS(root)
44);
45
46DEFINE_EVENT(cgroup_root, cgroup_remount,
47
48 TP_PROTO(struct cgroup_root *root),
49
50 TP_ARGS(root)
51);
52
53DECLARE_EVENT_CLASS(cgroup,
54
55 TP_PROTO(struct cgroup *cgrp),
56
57 TP_ARGS(cgrp),
58
59 TP_STRUCT__entry(
60 __field( int, root )
61 __field( int, id )
62 __field( int, level )
63 __dynamic_array(char, path,
64 cgrp->kn ? cgroup_path(cgrp, NULL, 0) + 1
65 : strlen("(null)"))
66 ),
67
68 TP_fast_assign(
69 __entry->root = cgrp->root->hierarchy_id;
70 __entry->id = cgrp->id;
71 __entry->level = cgrp->level;
72 if (cgrp->kn)
73 cgroup_path(cgrp, __get_dynamic_array(path),
74 __get_dynamic_array_len(path));
75 else
76 __assign_str(path, "(null)");
77 ),
78
79 TP_printk("root=%d id=%d level=%d path=%s",
80 __entry->root, __entry->id, __entry->level, __get_str(path))
81);
82
83DEFINE_EVENT(cgroup, cgroup_mkdir,
84
85 TP_PROTO(struct cgroup *cgroup),
86
87 TP_ARGS(cgroup)
88);
89
90DEFINE_EVENT(cgroup, cgroup_rmdir,
91
92 TP_PROTO(struct cgroup *cgroup),
93
94 TP_ARGS(cgroup)
95);
96
97DEFINE_EVENT(cgroup, cgroup_release,
98
99 TP_PROTO(struct cgroup *cgroup),
100
101 TP_ARGS(cgroup)
102);
103
104DEFINE_EVENT(cgroup, cgroup_rename,
105
106 TP_PROTO(struct cgroup *cgroup),
107
108 TP_ARGS(cgroup)
109);
110
111DECLARE_EVENT_CLASS(cgroup_migrate,
112
113 TP_PROTO(struct cgroup *dst_cgrp, struct task_struct *task, bool threadgroup),
114
115 TP_ARGS(dst_cgrp, task, threadgroup),
116
117 TP_STRUCT__entry(
118 __field( int, dst_root )
119 __field( int, dst_id )
120 __field( int, dst_level )
121 __dynamic_array(char, dst_path,
122 dst_cgrp->kn ? cgroup_path(dst_cgrp, NULL, 0) + 1
123 : strlen("(null)"))
124 __field( int, pid )
125 __string( comm, task->comm )
126 ),
127
128 TP_fast_assign(
129 __entry->dst_root = dst_cgrp->root->hierarchy_id;
130 __entry->dst_id = dst_cgrp->id;
131 __entry->dst_level = dst_cgrp->level;
132 if (dst_cgrp->kn)
133 cgroup_path(dst_cgrp, __get_dynamic_array(dst_path),
134 __get_dynamic_array_len(dst_path));
135 else
136 __assign_str(dst_path, "(null)");
137 __entry->pid = task->pid;
138 __assign_str(comm, task->comm);
139 ),
140
141 TP_printk("dst_root=%d dst_id=%d dst_level=%d dst_path=%s pid=%d comm=%s",
142 __entry->dst_root, __entry->dst_id, __entry->dst_level,
143 __get_str(dst_path), __entry->pid, __get_str(comm))
144);
145
146DEFINE_EVENT(cgroup_migrate, cgroup_attach_task,
147
148 TP_PROTO(struct cgroup *dst_cgrp, struct task_struct *task, bool threadgroup),
149
150 TP_ARGS(dst_cgrp, task, threadgroup)
151);
152
153DEFINE_EVENT(cgroup_migrate, cgroup_transfer_tasks,
154
155 TP_PROTO(struct cgroup *dst_cgrp, struct task_struct *task, bool threadgroup),
156
157 TP_ARGS(dst_cgrp, task, threadgroup)
158);
159
160#endif /* _TRACE_CGROUP_H */
161
162/* This part must be outside protection */
163#include <trace/define_trace.h>
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 44066158f0d1..85bc9beb046d 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -64,6 +64,9 @@
64#include <linux/file.h> 64#include <linux/file.h>
65#include <net/sock.h> 65#include <net/sock.h>
66 66
67#define CREATE_TRACE_POINTS
68#include <trace/events/cgroup.h>
69
67/* 70/*
68 * pidlists linger the following amount before being destroyed. The goal 71 * pidlists linger the following amount before being destroyed. The goal
69 * is avoiding frequent destruction in the middle of consecutive read calls 72 * is avoiding frequent destruction in the middle of consecutive read calls
@@ -1176,6 +1179,8 @@ static void cgroup_destroy_root(struct cgroup_root *root)
1176 struct cgroup *cgrp = &root->cgrp; 1179 struct cgroup *cgrp = &root->cgrp;
1177 struct cgrp_cset_link *link, *tmp_link; 1180 struct cgrp_cset_link *link, *tmp_link;
1178 1181
1182 trace_cgroup_destroy_root(root);
1183
1179 cgroup_lock_and_drain_offline(&cgrp_dfl_root.cgrp); 1184 cgroup_lock_and_drain_offline(&cgrp_dfl_root.cgrp);
1180 1185
1181 BUG_ON(atomic_read(&root->nr_cgrps)); 1186 BUG_ON(atomic_read(&root->nr_cgrps));
@@ -1874,6 +1879,9 @@ static int cgroup_remount(struct kernfs_root *kf_root, int *flags, char *data)
1874 strcpy(root->release_agent_path, opts.release_agent); 1879 strcpy(root->release_agent_path, opts.release_agent);
1875 spin_unlock(&release_agent_path_lock); 1880 spin_unlock(&release_agent_path_lock);
1876 } 1881 }
1882
1883 trace_cgroup_remount(root);
1884
1877 out_unlock: 1885 out_unlock:
1878 kfree(opts.release_agent); 1886 kfree(opts.release_agent);
1879 kfree(opts.name); 1887 kfree(opts.name);
@@ -2031,6 +2039,8 @@ static int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)
2031 if (ret) 2039 if (ret)
2032 goto destroy_root; 2040 goto destroy_root;
2033 2041
2042 trace_cgroup_setup_root(root);
2043
2034 /* 2044 /*
2035 * There must be no failure case after here, since rebinding takes 2045 * There must be no failure case after here, since rebinding takes
2036 * care of subsystems' refcounts, which are explicitly dropped in 2046 * care of subsystems' refcounts, which are explicitly dropped in
@@ -2315,22 +2325,18 @@ static struct file_system_type cgroup2_fs_type = {
2315 .fs_flags = FS_USERNS_MOUNT, 2325 .fs_flags = FS_USERNS_MOUNT,
2316}; 2326};
2317 2327
2318static char *cgroup_path_ns_locked(struct cgroup *cgrp, char *buf, size_t buflen, 2328static int cgroup_path_ns_locked(struct cgroup *cgrp, char *buf, size_t buflen,
2319 struct cgroup_namespace *ns) 2329 struct cgroup_namespace *ns)
2320{ 2330{
2321 struct cgroup *root = cset_cgroup_from_root(ns->root_cset, cgrp->root); 2331 struct cgroup *root = cset_cgroup_from_root(ns->root_cset, cgrp->root);
2322 int ret;
2323 2332
2324 ret = kernfs_path_from_node(cgrp->kn, root->kn, buf, buflen); 2333 return kernfs_path_from_node(cgrp->kn, root->kn, buf, buflen);
2325 if (ret < 0 || ret >= buflen)
2326 return NULL;
2327 return buf;
2328} 2334}
2329 2335
2330char *cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen, 2336int cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen,
2331 struct cgroup_namespace *ns) 2337 struct cgroup_namespace *ns)
2332{ 2338{
2333 char *ret; 2339 int ret;
2334 2340
2335 mutex_lock(&cgroup_mutex); 2341 mutex_lock(&cgroup_mutex);
2336 spin_lock_irq(&css_set_lock); 2342 spin_lock_irq(&css_set_lock);
@@ -2357,12 +2363,12 @@ EXPORT_SYMBOL_GPL(cgroup_path_ns);
2357 * 2363 *
2358 * Return value is the same as kernfs_path(). 2364 * Return value is the same as kernfs_path().
2359 */ 2365 */
2360char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen) 2366int task_cgroup_path(struct task_struct *task, char *buf, size_t buflen)
2361{ 2367{
2362 struct cgroup_root *root; 2368 struct cgroup_root *root;
2363 struct cgroup *cgrp; 2369 struct cgroup *cgrp;
2364 int hierarchy_id = 1; 2370 int hierarchy_id = 1;
2365 char *path = NULL; 2371 int ret;
2366 2372
2367 mutex_lock(&cgroup_mutex); 2373 mutex_lock(&cgroup_mutex);
2368 spin_lock_irq(&css_set_lock); 2374 spin_lock_irq(&css_set_lock);
@@ -2371,16 +2377,15 @@ char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen)
2371 2377
2372 if (root) { 2378 if (root) {
2373 cgrp = task_cgroup_from_root(task, root); 2379 cgrp = task_cgroup_from_root(task, root);
2374 path = cgroup_path_ns_locked(cgrp, buf, buflen, &init_cgroup_ns); 2380 ret = cgroup_path_ns_locked(cgrp, buf, buflen, &init_cgroup_ns);
2375 } else { 2381 } else {
2376 /* if no hierarchy exists, everyone is in "/" */ 2382 /* if no hierarchy exists, everyone is in "/" */
2377 if (strlcpy(buf, "/", buflen) < buflen) 2383 ret = strlcpy(buf, "/", buflen);
2378 path = buf;
2379 } 2384 }
2380 2385
2381 spin_unlock_irq(&css_set_lock); 2386 spin_unlock_irq(&css_set_lock);
2382 mutex_unlock(&cgroup_mutex); 2387 mutex_unlock(&cgroup_mutex);
2383 return path; 2388 return ret;
2384} 2389}
2385EXPORT_SYMBOL_GPL(task_cgroup_path); 2390EXPORT_SYMBOL_GPL(task_cgroup_path);
2386 2391
@@ -2830,6 +2835,10 @@ static int cgroup_attach_task(struct cgroup *dst_cgrp,
2830 ret = cgroup_migrate(leader, threadgroup, dst_cgrp->root); 2835 ret = cgroup_migrate(leader, threadgroup, dst_cgrp->root);
2831 2836
2832 cgroup_migrate_finish(&preloaded_csets); 2837 cgroup_migrate_finish(&preloaded_csets);
2838
2839 if (!ret)
2840 trace_cgroup_attach_task(dst_cgrp, leader, threadgroup);
2841
2833 return ret; 2842 return ret;
2834} 2843}
2835 2844
@@ -3611,6 +3620,8 @@ static int cgroup_rename(struct kernfs_node *kn, struct kernfs_node *new_parent,
3611 mutex_lock(&cgroup_mutex); 3620 mutex_lock(&cgroup_mutex);
3612 3621
3613 ret = kernfs_rename(kn, new_parent, new_name_str); 3622 ret = kernfs_rename(kn, new_parent, new_name_str);
3623 if (!ret)
3624 trace_cgroup_rename(cgrp);
3614 3625
3615 mutex_unlock(&cgroup_mutex); 3626 mutex_unlock(&cgroup_mutex);
3616 3627
@@ -4381,6 +4392,8 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from)
4381 4392
4382 if (task) { 4393 if (task) {
4383 ret = cgroup_migrate(task, false, to->root); 4394 ret = cgroup_migrate(task, false, to->root);
4395 if (!ret)
4396 trace_cgroup_transfer_tasks(to, task, false);
4384 put_task_struct(task); 4397 put_task_struct(task);
4385 } 4398 }
4386 } while (task && !ret); 4399 } while (task && !ret);
@@ -5046,6 +5059,8 @@ static void css_release_work_fn(struct work_struct *work)
5046 ss->css_released(css); 5059 ss->css_released(css);
5047 } else { 5060 } else {
5048 /* cgroup release path */ 5061 /* cgroup release path */
5062 trace_cgroup_release(cgrp);
5063
5049 cgroup_idr_remove(&cgrp->root->cgroup_idr, cgrp->id); 5064 cgroup_idr_remove(&cgrp->root->cgroup_idr, cgrp->id);
5050 cgrp->id = -1; 5065 cgrp->id = -1;
5051 5066
@@ -5332,6 +5347,8 @@ static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
5332 if (ret) 5347 if (ret)
5333 goto out_destroy; 5348 goto out_destroy;
5334 5349
5350 trace_cgroup_mkdir(cgrp);
5351
5335 /* let's create and online css's */ 5352 /* let's create and online css's */
5336 kernfs_activate(kn); 5353 kernfs_activate(kn);
5337 5354
@@ -5507,6 +5524,9 @@ static int cgroup_rmdir(struct kernfs_node *kn)
5507 5524
5508 ret = cgroup_destroy_locked(cgrp); 5525 ret = cgroup_destroy_locked(cgrp);
5509 5526
5527 if (!ret)
5528 trace_cgroup_rmdir(cgrp);
5529
5510 cgroup_kn_unlock(kn); 5530 cgroup_kn_unlock(kn);
5511 return ret; 5531 return ret;
5512} 5532}
@@ -5743,7 +5763,7 @@ core_initcall(cgroup_wq_init);
5743int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns, 5763int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
5744 struct pid *pid, struct task_struct *tsk) 5764 struct pid *pid, struct task_struct *tsk)
5745{ 5765{
5746 char *buf, *path; 5766 char *buf;
5747 int retval; 5767 int retval;
5748 struct cgroup_root *root; 5768 struct cgroup_root *root;
5749 5769
@@ -5786,18 +5806,18 @@ int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
5786 * " (deleted)" is appended to the cgroup path. 5806 * " (deleted)" is appended to the cgroup path.
5787 */ 5807 */
5788 if (cgroup_on_dfl(cgrp) || !(tsk->flags & PF_EXITING)) { 5808 if (cgroup_on_dfl(cgrp) || !(tsk->flags & PF_EXITING)) {
5789 path = cgroup_path_ns_locked(cgrp, buf, PATH_MAX, 5809 retval = cgroup_path_ns_locked(cgrp, buf, PATH_MAX,
5790 current->nsproxy->cgroup_ns); 5810 current->nsproxy->cgroup_ns);
5791 if (!path) { 5811 if (retval >= PATH_MAX)
5792 retval = -ENAMETOOLONG; 5812 retval = -ENAMETOOLONG;
5813 if (retval < 0)
5793 goto out_unlock; 5814 goto out_unlock;
5794 } 5815
5816 seq_puts(m, buf);
5795 } else { 5817 } else {
5796 path = "/"; 5818 seq_puts(m, "/");
5797 } 5819 }
5798 5820
5799 seq_puts(m, path);
5800
5801 if (cgroup_on_dfl(cgrp) && cgroup_is_dead(cgrp)) 5821 if (cgroup_on_dfl(cgrp) && cgroup_is_dead(cgrp))
5802 seq_puts(m, " (deleted)\n"); 5822 seq_puts(m, " (deleted)\n");
5803 else 5823 else
@@ -6062,8 +6082,9 @@ static void cgroup_release_agent(struct work_struct *work)
6062{ 6082{
6063 struct cgroup *cgrp = 6083 struct cgroup *cgrp =
6064 container_of(work, struct cgroup, release_agent_work); 6084 container_of(work, struct cgroup, release_agent_work);
6065 char *pathbuf = NULL, *agentbuf = NULL, *path; 6085 char *pathbuf = NULL, *agentbuf = NULL;
6066 char *argv[3], *envp[3]; 6086 char *argv[3], *envp[3];
6087 int ret;
6067 6088
6068 mutex_lock(&cgroup_mutex); 6089 mutex_lock(&cgroup_mutex);
6069 6090
@@ -6073,13 +6094,13 @@ static void cgroup_release_agent(struct work_struct *work)
6073 goto out; 6094 goto out;
6074 6095
6075 spin_lock_irq(&css_set_lock); 6096 spin_lock_irq(&css_set_lock);
6076 path = cgroup_path_ns_locked(cgrp, pathbuf, PATH_MAX, &init_cgroup_ns); 6097 ret = cgroup_path_ns_locked(cgrp, pathbuf, PATH_MAX, &init_cgroup_ns);
6077 spin_unlock_irq(&css_set_lock); 6098 spin_unlock_irq(&css_set_lock);
6078 if (!path) 6099 if (ret < 0 || ret >= PATH_MAX)
6079 goto out; 6100 goto out;
6080 6101
6081 argv[0] = agentbuf; 6102 argv[0] = agentbuf;
6082 argv[1] = path; 6103 argv[1] = pathbuf;
6083 argv[2] = NULL; 6104 argv[2] = NULL;
6084 6105
6085 /* minimal command environment */ 6106 /* minimal command environment */
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 2b4c20ab5bbe..29f815d2ef7e 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -2715,7 +2715,7 @@ void __cpuset_memory_pressure_bump(void)
2715int proc_cpuset_show(struct seq_file *m, struct pid_namespace *ns, 2715int proc_cpuset_show(struct seq_file *m, struct pid_namespace *ns,
2716 struct pid *pid, struct task_struct *tsk) 2716 struct pid *pid, struct task_struct *tsk)
2717{ 2717{
2718 char *buf, *p; 2718 char *buf;
2719 struct cgroup_subsys_state *css; 2719 struct cgroup_subsys_state *css;
2720 int retval; 2720 int retval;
2721 2721
@@ -2724,14 +2724,15 @@ int proc_cpuset_show(struct seq_file *m, struct pid_namespace *ns,
2724 if (!buf) 2724 if (!buf)
2725 goto out; 2725 goto out;
2726 2726
2727 retval = -ENAMETOOLONG;
2728 css = task_get_css(tsk, cpuset_cgrp_id); 2727 css = task_get_css(tsk, cpuset_cgrp_id);
2729 p = cgroup_path_ns(css->cgroup, buf, PATH_MAX, 2728 retval = cgroup_path_ns(css->cgroup, buf, PATH_MAX,
2730 current->nsproxy->cgroup_ns); 2729 current->nsproxy->cgroup_ns);
2731 css_put(css); 2730 css_put(css);
2732 if (!p) 2731 if (retval >= PATH_MAX)
2732 retval = -ENAMETOOLONG;
2733 if (retval < 0)
2733 goto out_free; 2734 goto out_free;
2734 seq_puts(m, p); 2735 seq_puts(m, buf);
2735 seq_putc(m, '\n'); 2736 seq_putc(m, '\n');
2736 retval = 0; 2737 retval = 0;
2737out_free: 2738out_free:
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 13935886a471..fa178b62ea79 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -415,7 +415,8 @@ static char *task_group_path(struct task_group *tg)
415 if (autogroup_path(tg, group_path, PATH_MAX)) 415 if (autogroup_path(tg, group_path, PATH_MAX))
416 return group_path; 416 return group_path;
417 417
418 return cgroup_path(tg->css.cgroup, group_path, PATH_MAX); 418 cgroup_path(tg->css.cgroup, group_path, PATH_MAX);
419 return group_path;
419} 420}
420#endif 421#endif
421 422