diff options
-rw-r--r-- | fs/Makefile | 1 | ||||
-rw-r--r-- | fs/tracefs/Makefile | 4 | ||||
-rw-r--r-- | fs/tracefs/inode.c | 650 | ||||
-rw-r--r-- | include/linux/tracefs.h | 45 | ||||
-rw-r--r-- | include/uapi/linux/magic.h | 2 | ||||
-rw-r--r-- | kernel/trace/ftrace.c | 22 | ||||
-rw-r--r-- | kernel/trace/trace.c | 187 | ||||
-rw-r--r-- | kernel/trace/trace.h | 2 | ||||
-rw-r--r-- | kernel/trace/trace_events.c | 32 | ||||
-rw-r--r-- | kernel/trace/trace_functions_graph.c | 7 | ||||
-rw-r--r-- | kernel/trace/trace_kprobe.c | 10 | ||||
-rw-r--r-- | kernel/trace/trace_probe.h | 2 | ||||
-rw-r--r-- | kernel/trace/trace_stat.c | 10 |
13 files changed, 832 insertions, 142 deletions
diff --git a/fs/Makefile b/fs/Makefile index a88ac4838c9e..cb92fd4c3172 100644 --- a/fs/Makefile +++ b/fs/Makefile | |||
@@ -118,6 +118,7 @@ obj-$(CONFIG_HOSTFS) += hostfs/ | |||
118 | obj-$(CONFIG_HPPFS) += hppfs/ | 118 | obj-$(CONFIG_HPPFS) += hppfs/ |
119 | obj-$(CONFIG_CACHEFILES) += cachefiles/ | 119 | obj-$(CONFIG_CACHEFILES) += cachefiles/ |
120 | obj-$(CONFIG_DEBUG_FS) += debugfs/ | 120 | obj-$(CONFIG_DEBUG_FS) += debugfs/ |
121 | obj-$(CONFIG_TRACING) += tracefs/ | ||
121 | obj-$(CONFIG_OCFS2_FS) += ocfs2/ | 122 | obj-$(CONFIG_OCFS2_FS) += ocfs2/ |
122 | obj-$(CONFIG_BTRFS_FS) += btrfs/ | 123 | obj-$(CONFIG_BTRFS_FS) += btrfs/ |
123 | obj-$(CONFIG_GFS2_FS) += gfs2/ | 124 | obj-$(CONFIG_GFS2_FS) += gfs2/ |
diff --git a/fs/tracefs/Makefile b/fs/tracefs/Makefile new file mode 100644 index 000000000000..82fa35b656c4 --- /dev/null +++ b/fs/tracefs/Makefile | |||
@@ -0,0 +1,4 @@ | |||
1 | tracefs-objs := inode.o | ||
2 | |||
3 | obj-$(CONFIG_TRACING) += tracefs.o | ||
4 | |||
diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c new file mode 100644 index 000000000000..d92bdf3b079a --- /dev/null +++ b/fs/tracefs/inode.c | |||
@@ -0,0 +1,650 @@ | |||
1 | /* | ||
2 | * inode.c - part of tracefs, a pseudo file system for activating tracing | ||
3 | * | ||
4 | * Based on debugfs by: Greg Kroah-Hartman <greg@kroah.com> | ||
5 | * | ||
6 | * Copyright (C) 2014 Red Hat Inc, author: Steven Rostedt <srostedt@redhat.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License version | ||
10 | * 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * tracefs is the file system that is used by the tracing infrastructure. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/fs.h> | ||
18 | #include <linux/mount.h> | ||
19 | #include <linux/kobject.h> | ||
20 | #include <linux/namei.h> | ||
21 | #include <linux/tracefs.h> | ||
22 | #include <linux/fsnotify.h> | ||
23 | #include <linux/seq_file.h> | ||
24 | #include <linux/parser.h> | ||
25 | #include <linux/magic.h> | ||
26 | #include <linux/slab.h> | ||
27 | |||
28 | #define TRACEFS_DEFAULT_MODE 0700 | ||
29 | |||
30 | static struct vfsmount *tracefs_mount; | ||
31 | static int tracefs_mount_count; | ||
32 | static bool tracefs_registered; | ||
33 | |||
34 | static ssize_t default_read_file(struct file *file, char __user *buf, | ||
35 | size_t count, loff_t *ppos) | ||
36 | { | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static ssize_t default_write_file(struct file *file, const char __user *buf, | ||
41 | size_t count, loff_t *ppos) | ||
42 | { | ||
43 | return count; | ||
44 | } | ||
45 | |||
46 | static const struct file_operations tracefs_file_operations = { | ||
47 | .read = default_read_file, | ||
48 | .write = default_write_file, | ||
49 | .open = simple_open, | ||
50 | .llseek = noop_llseek, | ||
51 | }; | ||
52 | |||
53 | static struct tracefs_dir_ops { | ||
54 | int (*mkdir)(const char *name); | ||
55 | int (*rmdir)(const char *name); | ||
56 | } tracefs_ops; | ||
57 | |||
58 | static char *get_dname(struct dentry *dentry) | ||
59 | { | ||
60 | const char *dname; | ||
61 | char *name; | ||
62 | int len = dentry->d_name.len; | ||
63 | |||
64 | dname = dentry->d_name.name; | ||
65 | name = kmalloc(len + 1, GFP_KERNEL); | ||
66 | if (!name) | ||
67 | return NULL; | ||
68 | memcpy(name, dname, len); | ||
69 | name[len] = 0; | ||
70 | return name; | ||
71 | } | ||
72 | |||
73 | static int tracefs_syscall_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode) | ||
74 | { | ||
75 | char *name; | ||
76 | int ret; | ||
77 | |||
78 | name = get_dname(dentry); | ||
79 | if (!name) | ||
80 | return -ENOMEM; | ||
81 | |||
82 | /* | ||
83 | * The mkdir call can call the generic functions that create | ||
84 | * the files within the tracefs system. It is up to the individual | ||
85 | * mkdir routine to handle races. | ||
86 | */ | ||
87 | mutex_unlock(&inode->i_mutex); | ||
88 | ret = tracefs_ops.mkdir(name); | ||
89 | mutex_lock(&inode->i_mutex); | ||
90 | |||
91 | kfree(name); | ||
92 | |||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry) | ||
97 | { | ||
98 | char *name; | ||
99 | int ret; | ||
100 | |||
101 | name = get_dname(dentry); | ||
102 | if (!name) | ||
103 | return -ENOMEM; | ||
104 | |||
105 | /* | ||
106 | * The rmdir call can call the generic functions that create | ||
107 | * the files within the tracefs system. It is up to the individual | ||
108 | * rmdir routine to handle races. | ||
109 | * This time we need to unlock not only the parent (inode) but | ||
110 | * also the directory that is being deleted. | ||
111 | */ | ||
112 | mutex_unlock(&inode->i_mutex); | ||
113 | mutex_unlock(&dentry->d_inode->i_mutex); | ||
114 | |||
115 | ret = tracefs_ops.rmdir(name); | ||
116 | |||
117 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); | ||
118 | mutex_lock(&dentry->d_inode->i_mutex); | ||
119 | |||
120 | kfree(name); | ||
121 | |||
122 | return ret; | ||
123 | } | ||
124 | |||
125 | static const struct inode_operations tracefs_dir_inode_operations = { | ||
126 | .lookup = simple_lookup, | ||
127 | .mkdir = tracefs_syscall_mkdir, | ||
128 | .rmdir = tracefs_syscall_rmdir, | ||
129 | }; | ||
130 | |||
131 | static struct inode *tracefs_get_inode(struct super_block *sb) | ||
132 | { | ||
133 | struct inode *inode = new_inode(sb); | ||
134 | if (inode) { | ||
135 | inode->i_ino = get_next_ino(); | ||
136 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
137 | } | ||
138 | return inode; | ||
139 | } | ||
140 | |||
141 | struct tracefs_mount_opts { | ||
142 | kuid_t uid; | ||
143 | kgid_t gid; | ||
144 | umode_t mode; | ||
145 | }; | ||
146 | |||
147 | enum { | ||
148 | Opt_uid, | ||
149 | Opt_gid, | ||
150 | Opt_mode, | ||
151 | Opt_err | ||
152 | }; | ||
153 | |||
154 | static const match_table_t tokens = { | ||
155 | {Opt_uid, "uid=%u"}, | ||
156 | {Opt_gid, "gid=%u"}, | ||
157 | {Opt_mode, "mode=%o"}, | ||
158 | {Opt_err, NULL} | ||
159 | }; | ||
160 | |||
161 | struct tracefs_fs_info { | ||
162 | struct tracefs_mount_opts mount_opts; | ||
163 | }; | ||
164 | |||
165 | static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts) | ||
166 | { | ||
167 | substring_t args[MAX_OPT_ARGS]; | ||
168 | int option; | ||
169 | int token; | ||
170 | kuid_t uid; | ||
171 | kgid_t gid; | ||
172 | char *p; | ||
173 | |||
174 | opts->mode = TRACEFS_DEFAULT_MODE; | ||
175 | |||
176 | while ((p = strsep(&data, ",")) != NULL) { | ||
177 | if (!*p) | ||
178 | continue; | ||
179 | |||
180 | token = match_token(p, tokens, args); | ||
181 | switch (token) { | ||
182 | case Opt_uid: | ||
183 | if (match_int(&args[0], &option)) | ||
184 | return -EINVAL; | ||
185 | uid = make_kuid(current_user_ns(), option); | ||
186 | if (!uid_valid(uid)) | ||
187 | return -EINVAL; | ||
188 | opts->uid = uid; | ||
189 | break; | ||
190 | case Opt_gid: | ||
191 | if (match_int(&args[0], &option)) | ||
192 | return -EINVAL; | ||
193 | gid = make_kgid(current_user_ns(), option); | ||
194 | if (!gid_valid(gid)) | ||
195 | return -EINVAL; | ||
196 | opts->gid = gid; | ||
197 | break; | ||
198 | case Opt_mode: | ||
199 | if (match_octal(&args[0], &option)) | ||
200 | return -EINVAL; | ||
201 | opts->mode = option & S_IALLUGO; | ||
202 | break; | ||
203 | /* | ||
204 | * We might like to report bad mount options here; | ||
205 | * but traditionally tracefs has ignored all mount options | ||
206 | */ | ||
207 | } | ||
208 | } | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | static int tracefs_apply_options(struct super_block *sb) | ||
214 | { | ||
215 | struct tracefs_fs_info *fsi = sb->s_fs_info; | ||
216 | struct inode *inode = sb->s_root->d_inode; | ||
217 | struct tracefs_mount_opts *opts = &fsi->mount_opts; | ||
218 | |||
219 | inode->i_mode &= ~S_IALLUGO; | ||
220 | inode->i_mode |= opts->mode; | ||
221 | |||
222 | inode->i_uid = opts->uid; | ||
223 | inode->i_gid = opts->gid; | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static int tracefs_remount(struct super_block *sb, int *flags, char *data) | ||
229 | { | ||
230 | int err; | ||
231 | struct tracefs_fs_info *fsi = sb->s_fs_info; | ||
232 | |||
233 | sync_filesystem(sb); | ||
234 | err = tracefs_parse_options(data, &fsi->mount_opts); | ||
235 | if (err) | ||
236 | goto fail; | ||
237 | |||
238 | tracefs_apply_options(sb); | ||
239 | |||
240 | fail: | ||
241 | return err; | ||
242 | } | ||
243 | |||
244 | static int tracefs_show_options(struct seq_file *m, struct dentry *root) | ||
245 | { | ||
246 | struct tracefs_fs_info *fsi = root->d_sb->s_fs_info; | ||
247 | struct tracefs_mount_opts *opts = &fsi->mount_opts; | ||
248 | |||
249 | if (!uid_eq(opts->uid, GLOBAL_ROOT_UID)) | ||
250 | seq_printf(m, ",uid=%u", | ||
251 | from_kuid_munged(&init_user_ns, opts->uid)); | ||
252 | if (!gid_eq(opts->gid, GLOBAL_ROOT_GID)) | ||
253 | seq_printf(m, ",gid=%u", | ||
254 | from_kgid_munged(&init_user_ns, opts->gid)); | ||
255 | if (opts->mode != TRACEFS_DEFAULT_MODE) | ||
256 | seq_printf(m, ",mode=%o", opts->mode); | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static const struct super_operations tracefs_super_operations = { | ||
262 | .statfs = simple_statfs, | ||
263 | .remount_fs = tracefs_remount, | ||
264 | .show_options = tracefs_show_options, | ||
265 | }; | ||
266 | |||
267 | static int trace_fill_super(struct super_block *sb, void *data, int silent) | ||
268 | { | ||
269 | static struct tree_descr trace_files[] = {{""}}; | ||
270 | struct tracefs_fs_info *fsi; | ||
271 | int err; | ||
272 | |||
273 | save_mount_options(sb, data); | ||
274 | |||
275 | fsi = kzalloc(sizeof(struct tracefs_fs_info), GFP_KERNEL); | ||
276 | sb->s_fs_info = fsi; | ||
277 | if (!fsi) { | ||
278 | err = -ENOMEM; | ||
279 | goto fail; | ||
280 | } | ||
281 | |||
282 | err = tracefs_parse_options(data, &fsi->mount_opts); | ||
283 | if (err) | ||
284 | goto fail; | ||
285 | |||
286 | err = simple_fill_super(sb, TRACEFS_MAGIC, trace_files); | ||
287 | if (err) | ||
288 | goto fail; | ||
289 | |||
290 | sb->s_op = &tracefs_super_operations; | ||
291 | |||
292 | tracefs_apply_options(sb); | ||
293 | |||
294 | return 0; | ||
295 | |||
296 | fail: | ||
297 | kfree(fsi); | ||
298 | sb->s_fs_info = NULL; | ||
299 | return err; | ||
300 | } | ||
301 | |||
302 | static struct dentry *trace_mount(struct file_system_type *fs_type, | ||
303 | int flags, const char *dev_name, | ||
304 | void *data) | ||
305 | { | ||
306 | return mount_single(fs_type, flags, data, trace_fill_super); | ||
307 | } | ||
308 | |||
309 | static struct file_system_type trace_fs_type = { | ||
310 | .owner = THIS_MODULE, | ||
311 | .name = "tracefs", | ||
312 | .mount = trace_mount, | ||
313 | .kill_sb = kill_litter_super, | ||
314 | }; | ||
315 | MODULE_ALIAS_FS("tracefs"); | ||
316 | |||
317 | static struct dentry *start_creating(const char *name, struct dentry *parent) | ||
318 | { | ||
319 | struct dentry *dentry; | ||
320 | int error; | ||
321 | |||
322 | pr_debug("tracefs: creating file '%s'\n",name); | ||
323 | |||
324 | error = simple_pin_fs(&trace_fs_type, &tracefs_mount, | ||
325 | &tracefs_mount_count); | ||
326 | if (error) | ||
327 | return ERR_PTR(error); | ||
328 | |||
329 | /* If the parent is not specified, we create it in the root. | ||
330 | * We need the root dentry to do this, which is in the super | ||
331 | * block. A pointer to that is in the struct vfsmount that we | ||
332 | * have around. | ||
333 | */ | ||
334 | if (!parent) | ||
335 | parent = tracefs_mount->mnt_root; | ||
336 | |||
337 | mutex_lock(&parent->d_inode->i_mutex); | ||
338 | dentry = lookup_one_len(name, parent, strlen(name)); | ||
339 | if (!IS_ERR(dentry) && dentry->d_inode) { | ||
340 | dput(dentry); | ||
341 | dentry = ERR_PTR(-EEXIST); | ||
342 | } | ||
343 | if (IS_ERR(dentry)) | ||
344 | mutex_unlock(&parent->d_inode->i_mutex); | ||
345 | return dentry; | ||
346 | } | ||
347 | |||
348 | static struct dentry *failed_creating(struct dentry *dentry) | ||
349 | { | ||
350 | mutex_unlock(&dentry->d_parent->d_inode->i_mutex); | ||
351 | dput(dentry); | ||
352 | simple_release_fs(&tracefs_mount, &tracefs_mount_count); | ||
353 | return NULL; | ||
354 | } | ||
355 | |||
356 | static struct dentry *end_creating(struct dentry *dentry) | ||
357 | { | ||
358 | mutex_unlock(&dentry->d_parent->d_inode->i_mutex); | ||
359 | return dentry; | ||
360 | } | ||
361 | |||
362 | /** | ||
363 | * tracefs_create_file - create a file in the tracefs filesystem | ||
364 | * @name: a pointer to a string containing the name of the file to create. | ||
365 | * @mode: the permission that the file should have. | ||
366 | * @parent: a pointer to the parent dentry for this file. This should be a | ||
367 | * directory dentry if set. If this parameter is NULL, then the | ||
368 | * file will be created in the root of the tracefs filesystem. | ||
369 | * @data: a pointer to something that the caller will want to get to later | ||
370 | * on. The inode.i_private pointer will point to this value on | ||
371 | * the open() call. | ||
372 | * @fops: a pointer to a struct file_operations that should be used for | ||
373 | * this file. | ||
374 | * | ||
375 | * This is the basic "create a file" function for tracefs. It allows for a | ||
376 | * wide range of flexibility in creating a file, or a directory (if you want | ||
377 | * to create a directory, the tracefs_create_dir() function is | ||
378 | * recommended to be used instead.) | ||
379 | * | ||
380 | * This function will return a pointer to a dentry if it succeeds. This | ||
381 | * pointer must be passed to the tracefs_remove() function when the file is | ||
382 | * to be removed (no automatic cleanup happens if your module is unloaded, | ||
383 | * you are responsible here.) If an error occurs, %NULL will be returned. | ||
384 | * | ||
385 | * If tracefs is not enabled in the kernel, the value -%ENODEV will be | ||
386 | * returned. | ||
387 | */ | ||
388 | struct dentry *tracefs_create_file(const char *name, umode_t mode, | ||
389 | struct dentry *parent, void *data, | ||
390 | const struct file_operations *fops) | ||
391 | { | ||
392 | struct dentry *dentry; | ||
393 | struct inode *inode; | ||
394 | |||
395 | if (!(mode & S_IFMT)) | ||
396 | mode |= S_IFREG; | ||
397 | BUG_ON(!S_ISREG(mode)); | ||
398 | dentry = start_creating(name, parent); | ||
399 | |||
400 | if (IS_ERR(dentry)) | ||
401 | return NULL; | ||
402 | |||
403 | inode = tracefs_get_inode(dentry->d_sb); | ||
404 | if (unlikely(!inode)) | ||
405 | return failed_creating(dentry); | ||
406 | |||
407 | inode->i_mode = mode; | ||
408 | inode->i_fop = fops ? fops : &tracefs_file_operations; | ||
409 | inode->i_private = data; | ||
410 | d_instantiate(dentry, inode); | ||
411 | fsnotify_create(dentry->d_parent->d_inode, dentry); | ||
412 | return end_creating(dentry); | ||
413 | } | ||
414 | |||
415 | static struct dentry *__create_dir(const char *name, struct dentry *parent, | ||
416 | const struct inode_operations *ops) | ||
417 | { | ||
418 | struct dentry *dentry = start_creating(name, parent); | ||
419 | struct inode *inode; | ||
420 | |||
421 | if (IS_ERR(dentry)) | ||
422 | return NULL; | ||
423 | |||
424 | inode = tracefs_get_inode(dentry->d_sb); | ||
425 | if (unlikely(!inode)) | ||
426 | return failed_creating(dentry); | ||
427 | |||
428 | inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; | ||
429 | inode->i_op = ops; | ||
430 | inode->i_fop = &simple_dir_operations; | ||
431 | |||
432 | /* directory inodes start off with i_nlink == 2 (for "." entry) */ | ||
433 | inc_nlink(inode); | ||
434 | d_instantiate(dentry, inode); | ||
435 | inc_nlink(dentry->d_parent->d_inode); | ||
436 | fsnotify_mkdir(dentry->d_parent->d_inode, dentry); | ||
437 | return end_creating(dentry); | ||
438 | } | ||
439 | |||
440 | /** | ||
441 | * tracefs_create_dir - create a directory in the tracefs filesystem | ||
442 | * @name: a pointer to a string containing the name of the directory to | ||
443 | * create. | ||
444 | * @parent: a pointer to the parent dentry for this file. This should be a | ||
445 | * directory dentry if set. If this parameter is NULL, then the | ||
446 | * directory will be created in the root of the tracefs filesystem. | ||
447 | * | ||
448 | * This function creates a directory in tracefs with the given name. | ||
449 | * | ||
450 | * This function will return a pointer to a dentry if it succeeds. This | ||
451 | * pointer must be passed to the tracefs_remove() function when the file is | ||
452 | * to be removed. If an error occurs, %NULL will be returned. | ||
453 | * | ||
454 | * If tracing is not enabled in the kernel, the value -%ENODEV will be | ||
455 | * returned. | ||
456 | */ | ||
457 | struct dentry *tracefs_create_dir(const char *name, struct dentry *parent) | ||
458 | { | ||
459 | return __create_dir(name, parent, &simple_dir_inode_operations); | ||
460 | } | ||
461 | |||
462 | /** | ||
463 | * tracefs_create_instance_dir - create the tracing instances directory | ||
464 | * @name: The name of the instances directory to create | ||
465 | * @parent: The parent directory that the instances directory will exist | ||
466 | * @mkdir: The function to call when a mkdir is performed. | ||
467 | * @rmdir: The function to call when a rmdir is performed. | ||
468 | * | ||
469 | * Only one instances directory is allowed. | ||
470 | * | ||
471 | * The instances directory is special as it allows for mkdir and rmdir to | ||
472 | * to be done by userspace. When a mkdir or rmdir is performed, the inode | ||
473 | * locks are released and the methhods passed in (@mkdir and @rmdir) are | ||
474 | * called without locks and with the name of the directory being created | ||
475 | * within the instances directory. | ||
476 | * | ||
477 | * Returns the dentry of the instances directory. | ||
478 | */ | ||
479 | struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent, | ||
480 | int (*mkdir)(const char *name), | ||
481 | int (*rmdir)(const char *name)) | ||
482 | { | ||
483 | struct dentry *dentry; | ||
484 | |||
485 | /* Only allow one instance of the instances directory. */ | ||
486 | if (WARN_ON(tracefs_ops.mkdir || tracefs_ops.rmdir)) | ||
487 | return NULL; | ||
488 | |||
489 | dentry = __create_dir(name, parent, &tracefs_dir_inode_operations); | ||
490 | if (!dentry) | ||
491 | return NULL; | ||
492 | |||
493 | tracefs_ops.mkdir = mkdir; | ||
494 | tracefs_ops.rmdir = rmdir; | ||
495 | |||
496 | return dentry; | ||
497 | } | ||
498 | |||
499 | static inline int tracefs_positive(struct dentry *dentry) | ||
500 | { | ||
501 | return dentry->d_inode && !d_unhashed(dentry); | ||
502 | } | ||
503 | |||
504 | static int __tracefs_remove(struct dentry *dentry, struct dentry *parent) | ||
505 | { | ||
506 | int ret = 0; | ||
507 | |||
508 | if (tracefs_positive(dentry)) { | ||
509 | if (dentry->d_inode) { | ||
510 | dget(dentry); | ||
511 | switch (dentry->d_inode->i_mode & S_IFMT) { | ||
512 | case S_IFDIR: | ||
513 | ret = simple_rmdir(parent->d_inode, dentry); | ||
514 | break; | ||
515 | default: | ||
516 | simple_unlink(parent->d_inode, dentry); | ||
517 | break; | ||
518 | } | ||
519 | if (!ret) | ||
520 | d_delete(dentry); | ||
521 | dput(dentry); | ||
522 | } | ||
523 | } | ||
524 | return ret; | ||
525 | } | ||
526 | |||
527 | /** | ||
528 | * tracefs_remove - removes a file or directory from the tracefs filesystem | ||
529 | * @dentry: a pointer to a the dentry of the file or directory to be | ||
530 | * removed. | ||
531 | * | ||
532 | * This function removes a file or directory in tracefs that was previously | ||
533 | * created with a call to another tracefs function (like | ||
534 | * tracefs_create_file() or variants thereof.) | ||
535 | */ | ||
536 | void tracefs_remove(struct dentry *dentry) | ||
537 | { | ||
538 | struct dentry *parent; | ||
539 | int ret; | ||
540 | |||
541 | if (IS_ERR_OR_NULL(dentry)) | ||
542 | return; | ||
543 | |||
544 | parent = dentry->d_parent; | ||
545 | if (!parent || !parent->d_inode) | ||
546 | return; | ||
547 | |||
548 | mutex_lock(&parent->d_inode->i_mutex); | ||
549 | ret = __tracefs_remove(dentry, parent); | ||
550 | mutex_unlock(&parent->d_inode->i_mutex); | ||
551 | if (!ret) | ||
552 | simple_release_fs(&tracefs_mount, &tracefs_mount_count); | ||
553 | } | ||
554 | |||
555 | /** | ||
556 | * tracefs_remove_recursive - recursively removes a directory | ||
557 | * @dentry: a pointer to a the dentry of the directory to be removed. | ||
558 | * | ||
559 | * This function recursively removes a directory tree in tracefs that | ||
560 | * was previously created with a call to another tracefs function | ||
561 | * (like tracefs_create_file() or variants thereof.) | ||
562 | */ | ||
563 | void tracefs_remove_recursive(struct dentry *dentry) | ||
564 | { | ||
565 | struct dentry *child, *parent; | ||
566 | |||
567 | if (IS_ERR_OR_NULL(dentry)) | ||
568 | return; | ||
569 | |||
570 | parent = dentry->d_parent; | ||
571 | if (!parent || !parent->d_inode) | ||
572 | return; | ||
573 | |||
574 | parent = dentry; | ||
575 | down: | ||
576 | mutex_lock(&parent->d_inode->i_mutex); | ||
577 | loop: | ||
578 | /* | ||
579 | * The parent->d_subdirs is protected by the d_lock. Outside that | ||
580 | * lock, the child can be unlinked and set to be freed which can | ||
581 | * use the d_u.d_child as the rcu head and corrupt this list. | ||
582 | */ | ||
583 | spin_lock(&parent->d_lock); | ||
584 | list_for_each_entry(child, &parent->d_subdirs, d_child) { | ||
585 | if (!tracefs_positive(child)) | ||
586 | continue; | ||
587 | |||
588 | /* perhaps simple_empty(child) makes more sense */ | ||
589 | if (!list_empty(&child->d_subdirs)) { | ||
590 | spin_unlock(&parent->d_lock); | ||
591 | mutex_unlock(&parent->d_inode->i_mutex); | ||
592 | parent = child; | ||
593 | goto down; | ||
594 | } | ||
595 | |||
596 | spin_unlock(&parent->d_lock); | ||
597 | |||
598 | if (!__tracefs_remove(child, parent)) | ||
599 | simple_release_fs(&tracefs_mount, &tracefs_mount_count); | ||
600 | |||
601 | /* | ||
602 | * The parent->d_lock protects agaist child from unlinking | ||
603 | * from d_subdirs. When releasing the parent->d_lock we can | ||
604 | * no longer trust that the next pointer is valid. | ||
605 | * Restart the loop. We'll skip this one with the | ||
606 | * tracefs_positive() check. | ||
607 | */ | ||
608 | goto loop; | ||
609 | } | ||
610 | spin_unlock(&parent->d_lock); | ||
611 | |||
612 | mutex_unlock(&parent->d_inode->i_mutex); | ||
613 | child = parent; | ||
614 | parent = parent->d_parent; | ||
615 | mutex_lock(&parent->d_inode->i_mutex); | ||
616 | |||
617 | if (child != dentry) | ||
618 | /* go up */ | ||
619 | goto loop; | ||
620 | |||
621 | if (!__tracefs_remove(child, parent)) | ||
622 | simple_release_fs(&tracefs_mount, &tracefs_mount_count); | ||
623 | mutex_unlock(&parent->d_inode->i_mutex); | ||
624 | } | ||
625 | |||
626 | /** | ||
627 | * tracefs_initialized - Tells whether tracefs has been registered | ||
628 | */ | ||
629 | bool tracefs_initialized(void) | ||
630 | { | ||
631 | return tracefs_registered; | ||
632 | } | ||
633 | |||
634 | static struct kobject *trace_kobj; | ||
635 | |||
636 | static int __init tracefs_init(void) | ||
637 | { | ||
638 | int retval; | ||
639 | |||
640 | trace_kobj = kobject_create_and_add("tracing", kernel_kobj); | ||
641 | if (!trace_kobj) | ||
642 | return -EINVAL; | ||
643 | |||
644 | retval = register_filesystem(&trace_fs_type); | ||
645 | if (!retval) | ||
646 | tracefs_registered = true; | ||
647 | |||
648 | return retval; | ||
649 | } | ||
650 | core_initcall(tracefs_init); | ||
diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h new file mode 100644 index 000000000000..5b727a17beee --- /dev/null +++ b/include/linux/tracefs.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * tracefs.h - a pseudo file system for activating tracing | ||
3 | * | ||
4 | * Based on debugfs by: 2004 Greg Kroah-Hartman <greg@kroah.com> | ||
5 | * | ||
6 | * Copyright (C) 2014 Red Hat Inc, author: Steven Rostedt <srostedt@redhat.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License version | ||
10 | * 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * tracefs is the file system that is used by the tracing infrastructure. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifndef _TRACEFS_H_ | ||
17 | #define _TRACEFS_H_ | ||
18 | |||
19 | #include <linux/fs.h> | ||
20 | #include <linux/seq_file.h> | ||
21 | |||
22 | #include <linux/types.h> | ||
23 | |||
24 | struct file_operations; | ||
25 | |||
26 | #ifdef CONFIG_TRACING | ||
27 | |||
28 | struct dentry *tracefs_create_file(const char *name, umode_t mode, | ||
29 | struct dentry *parent, void *data, | ||
30 | const struct file_operations *fops); | ||
31 | |||
32 | struct dentry *tracefs_create_dir(const char *name, struct dentry *parent); | ||
33 | |||
34 | void tracefs_remove(struct dentry *dentry); | ||
35 | void tracefs_remove_recursive(struct dentry *dentry); | ||
36 | |||
37 | struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent, | ||
38 | int (*mkdir)(const char *name), | ||
39 | int (*rmdir)(const char *name)); | ||
40 | |||
41 | bool tracefs_initialized(void); | ||
42 | |||
43 | #endif /* CONFIG_TRACING */ | ||
44 | |||
45 | #endif | ||
diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h index 7d664ea85ebd..7b1425a6b370 100644 --- a/include/uapi/linux/magic.h +++ b/include/uapi/linux/magic.h | |||
@@ -58,6 +58,8 @@ | |||
58 | 58 | ||
59 | #define STACK_END_MAGIC 0x57AC6E9D | 59 | #define STACK_END_MAGIC 0x57AC6E9D |
60 | 60 | ||
61 | #define TRACEFS_MAGIC 0x74726163 | ||
62 | |||
61 | #define V9FS_MAGIC 0x01021997 | 63 | #define V9FS_MAGIC 0x01021997 |
62 | 64 | ||
63 | #define BDEVFS_MAGIC 0x62646576 | 65 | #define BDEVFS_MAGIC 0x62646576 |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 4f228024055b..5a2e0b53af30 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/kallsyms.h> | 18 | #include <linux/kallsyms.h> |
19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
20 | #include <linux/suspend.h> | 20 | #include <linux/suspend.h> |
21 | #include <linux/debugfs.h> | 21 | #include <linux/tracefs.h> |
22 | #include <linux/hardirq.h> | 22 | #include <linux/hardirq.h> |
23 | #include <linux/kthread.h> | 23 | #include <linux/kthread.h> |
24 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
@@ -1008,7 +1008,7 @@ static struct tracer_stat function_stats __initdata = { | |||
1008 | .stat_show = function_stat_show | 1008 | .stat_show = function_stat_show |
1009 | }; | 1009 | }; |
1010 | 1010 | ||
1011 | static __init void ftrace_profile_debugfs(struct dentry *d_tracer) | 1011 | static __init void ftrace_profile_tracefs(struct dentry *d_tracer) |
1012 | { | 1012 | { |
1013 | struct ftrace_profile_stat *stat; | 1013 | struct ftrace_profile_stat *stat; |
1014 | struct dentry *entry; | 1014 | struct dentry *entry; |
@@ -1044,15 +1044,15 @@ static __init void ftrace_profile_debugfs(struct dentry *d_tracer) | |||
1044 | } | 1044 | } |
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | entry = debugfs_create_file("function_profile_enabled", 0644, | 1047 | entry = tracefs_create_file("function_profile_enabled", 0644, |
1048 | d_tracer, NULL, &ftrace_profile_fops); | 1048 | d_tracer, NULL, &ftrace_profile_fops); |
1049 | if (!entry) | 1049 | if (!entry) |
1050 | pr_warning("Could not create debugfs " | 1050 | pr_warning("Could not create tracefs " |
1051 | "'function_profile_enabled' entry\n"); | 1051 | "'function_profile_enabled' entry\n"); |
1052 | } | 1052 | } |
1053 | 1053 | ||
1054 | #else /* CONFIG_FUNCTION_PROFILER */ | 1054 | #else /* CONFIG_FUNCTION_PROFILER */ |
1055 | static __init void ftrace_profile_debugfs(struct dentry *d_tracer) | 1055 | static __init void ftrace_profile_tracefs(struct dentry *d_tracer) |
1056 | { | 1056 | { |
1057 | } | 1057 | } |
1058 | #endif /* CONFIG_FUNCTION_PROFILER */ | 1058 | #endif /* CONFIG_FUNCTION_PROFILER */ |
@@ -4712,7 +4712,7 @@ void ftrace_destroy_filter_files(struct ftrace_ops *ops) | |||
4712 | mutex_unlock(&ftrace_lock); | 4712 | mutex_unlock(&ftrace_lock); |
4713 | } | 4713 | } |
4714 | 4714 | ||
4715 | static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer) | 4715 | static __init int ftrace_init_dyn_tracefs(struct dentry *d_tracer) |
4716 | { | 4716 | { |
4717 | 4717 | ||
4718 | trace_create_file("available_filter_functions", 0444, | 4718 | trace_create_file("available_filter_functions", 0444, |
@@ -5020,7 +5020,7 @@ static int __init ftrace_nodyn_init(void) | |||
5020 | } | 5020 | } |
5021 | core_initcall(ftrace_nodyn_init); | 5021 | core_initcall(ftrace_nodyn_init); |
5022 | 5022 | ||
5023 | static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } | 5023 | static inline int ftrace_init_dyn_tracefs(struct dentry *d_tracer) { return 0; } |
5024 | static inline void ftrace_startup_enable(int command) { } | 5024 | static inline void ftrace_startup_enable(int command) { } |
5025 | static inline void ftrace_startup_all(int command) { } | 5025 | static inline void ftrace_startup_all(int command) { } |
5026 | /* Keep as macros so we do not need to define the commands */ | 5026 | /* Keep as macros so we do not need to define the commands */ |
@@ -5473,7 +5473,7 @@ static const struct file_operations ftrace_pid_fops = { | |||
5473 | .release = ftrace_pid_release, | 5473 | .release = ftrace_pid_release, |
5474 | }; | 5474 | }; |
5475 | 5475 | ||
5476 | static __init int ftrace_init_debugfs(void) | 5476 | static __init int ftrace_init_tracefs(void) |
5477 | { | 5477 | { |
5478 | struct dentry *d_tracer; | 5478 | struct dentry *d_tracer; |
5479 | 5479 | ||
@@ -5481,16 +5481,16 @@ static __init int ftrace_init_debugfs(void) | |||
5481 | if (IS_ERR(d_tracer)) | 5481 | if (IS_ERR(d_tracer)) |
5482 | return 0; | 5482 | return 0; |
5483 | 5483 | ||
5484 | ftrace_init_dyn_debugfs(d_tracer); | 5484 | ftrace_init_dyn_tracefs(d_tracer); |
5485 | 5485 | ||
5486 | trace_create_file("set_ftrace_pid", 0644, d_tracer, | 5486 | trace_create_file("set_ftrace_pid", 0644, d_tracer, |
5487 | NULL, &ftrace_pid_fops); | 5487 | NULL, &ftrace_pid_fops); |
5488 | 5488 | ||
5489 | ftrace_profile_debugfs(d_tracer); | 5489 | ftrace_profile_tracefs(d_tracer); |
5490 | 5490 | ||
5491 | return 0; | 5491 | return 0; |
5492 | } | 5492 | } |
5493 | fs_initcall(ftrace_init_debugfs); | 5493 | fs_initcall(ftrace_init_tracefs); |
5494 | 5494 | ||
5495 | /** | 5495 | /** |
5496 | * ftrace_kill - kill ftrace | 5496 | * ftrace_kill - kill ftrace |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 62c6506d663f..bcfa2add6dda 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/notifier.h> | 20 | #include <linux/notifier.h> |
21 | #include <linux/irqflags.h> | 21 | #include <linux/irqflags.h> |
22 | #include <linux/debugfs.h> | 22 | #include <linux/debugfs.h> |
23 | #include <linux/tracefs.h> | ||
23 | #include <linux/pagemap.h> | 24 | #include <linux/pagemap.h> |
24 | #include <linux/hardirq.h> | 25 | #include <linux/hardirq.h> |
25 | #include <linux/linkage.h> | 26 | #include <linux/linkage.h> |
@@ -31,6 +32,7 @@ | |||
31 | #include <linux/splice.h> | 32 | #include <linux/splice.h> |
32 | #include <linux/kdebug.h> | 33 | #include <linux/kdebug.h> |
33 | #include <linux/string.h> | 34 | #include <linux/string.h> |
35 | #include <linux/mount.h> | ||
34 | #include <linux/rwsem.h> | 36 | #include <linux/rwsem.h> |
35 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
36 | #include <linux/ctype.h> | 38 | #include <linux/ctype.h> |
@@ -4105,9 +4107,24 @@ static void tracing_set_nop(struct trace_array *tr) | |||
4105 | tr->current_trace = &nop_trace; | 4107 | tr->current_trace = &nop_trace; |
4106 | } | 4108 | } |
4107 | 4109 | ||
4108 | static int tracing_set_tracer(struct trace_array *tr, const char *buf) | 4110 | static void update_tracer_options(struct trace_array *tr, struct tracer *t) |
4109 | { | 4111 | { |
4110 | static struct trace_option_dentry *topts; | 4112 | static struct trace_option_dentry *topts; |
4113 | |||
4114 | /* Only enable if the directory has been created already. */ | ||
4115 | if (!tr->dir) | ||
4116 | return; | ||
4117 | |||
4118 | /* Currently, only the top instance has options */ | ||
4119 | if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL)) | ||
4120 | return; | ||
4121 | |||
4122 | destroy_trace_option_files(topts); | ||
4123 | topts = create_trace_option_files(tr, t); | ||
4124 | } | ||
4125 | |||
4126 | static int tracing_set_tracer(struct trace_array *tr, const char *buf) | ||
4127 | { | ||
4111 | struct tracer *t; | 4128 | struct tracer *t; |
4112 | #ifdef CONFIG_TRACER_MAX_TRACE | 4129 | #ifdef CONFIG_TRACER_MAX_TRACE |
4113 | bool had_max_tr; | 4130 | bool had_max_tr; |
@@ -4172,11 +4189,7 @@ static int tracing_set_tracer(struct trace_array *tr, const char *buf) | |||
4172 | free_snapshot(tr); | 4189 | free_snapshot(tr); |
4173 | } | 4190 | } |
4174 | #endif | 4191 | #endif |
4175 | /* Currently, only the top instance has options */ | 4192 | update_tracer_options(tr, t); |
4176 | if (tr->flags & TRACE_ARRAY_FL_GLOBAL) { | ||
4177 | destroy_trace_option_files(topts); | ||
4178 | topts = create_trace_option_files(tr, t); | ||
4179 | } | ||
4180 | 4193 | ||
4181 | #ifdef CONFIG_TRACER_MAX_TRACE | 4194 | #ifdef CONFIG_TRACER_MAX_TRACE |
4182 | if (t->use_max_tr && !had_max_tr) { | 4195 | if (t->use_max_tr && !had_max_tr) { |
@@ -5817,6 +5830,14 @@ static inline __init int register_snapshot_cmd(void) { return 0; } | |||
5817 | 5830 | ||
5818 | static struct dentry *tracing_get_dentry(struct trace_array *tr) | 5831 | static struct dentry *tracing_get_dentry(struct trace_array *tr) |
5819 | { | 5832 | { |
5833 | if (WARN_ON(!tr->dir)) | ||
5834 | return ERR_PTR(-ENODEV); | ||
5835 | |||
5836 | /* Top directory uses NULL as the parent */ | ||
5837 | if (tr->flags & TRACE_ARRAY_FL_GLOBAL) | ||
5838 | return NULL; | ||
5839 | |||
5840 | /* All sub buffers have a descriptor */ | ||
5820 | return tr->dir; | 5841 | return tr->dir; |
5821 | } | 5842 | } |
5822 | 5843 | ||
@@ -5831,10 +5852,10 @@ static struct dentry *tracing_dentry_percpu(struct trace_array *tr, int cpu) | |||
5831 | if (IS_ERR(d_tracer)) | 5852 | if (IS_ERR(d_tracer)) |
5832 | return NULL; | 5853 | return NULL; |
5833 | 5854 | ||
5834 | tr->percpu_dir = debugfs_create_dir("per_cpu", d_tracer); | 5855 | tr->percpu_dir = tracefs_create_dir("per_cpu", d_tracer); |
5835 | 5856 | ||
5836 | WARN_ONCE(!tr->percpu_dir, | 5857 | WARN_ONCE(!tr->percpu_dir, |
5837 | "Could not create debugfs directory 'per_cpu/%d'\n", cpu); | 5858 | "Could not create tracefs directory 'per_cpu/%d'\n", cpu); |
5838 | 5859 | ||
5839 | return tr->percpu_dir; | 5860 | return tr->percpu_dir; |
5840 | } | 5861 | } |
@@ -5851,7 +5872,7 @@ trace_create_cpu_file(const char *name, umode_t mode, struct dentry *parent, | |||
5851 | } | 5872 | } |
5852 | 5873 | ||
5853 | static void | 5874 | static void |
5854 | tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) | 5875 | tracing_init_tracefs_percpu(struct trace_array *tr, long cpu) |
5855 | { | 5876 | { |
5856 | struct dentry *d_percpu = tracing_dentry_percpu(tr, cpu); | 5877 | struct dentry *d_percpu = tracing_dentry_percpu(tr, cpu); |
5857 | struct dentry *d_cpu; | 5878 | struct dentry *d_cpu; |
@@ -5861,9 +5882,9 @@ tracing_init_debugfs_percpu(struct trace_array *tr, long cpu) | |||
5861 | return; | 5882 | return; |
5862 | 5883 | ||
5863 | snprintf(cpu_dir, 30, "cpu%ld", cpu); | 5884 | snprintf(cpu_dir, 30, "cpu%ld", cpu); |
5864 | d_cpu = debugfs_create_dir(cpu_dir, d_percpu); | 5885 | d_cpu = tracefs_create_dir(cpu_dir, d_percpu); |
5865 | if (!d_cpu) { | 5886 | if (!d_cpu) { |
5866 | pr_warning("Could not create debugfs '%s' entry\n", cpu_dir); | 5887 | pr_warning("Could not create tracefs '%s' entry\n", cpu_dir); |
5867 | return; | 5888 | return; |
5868 | } | 5889 | } |
5869 | 5890 | ||
@@ -6015,9 +6036,9 @@ struct dentry *trace_create_file(const char *name, | |||
6015 | { | 6036 | { |
6016 | struct dentry *ret; | 6037 | struct dentry *ret; |
6017 | 6038 | ||
6018 | ret = debugfs_create_file(name, mode, parent, data, fops); | 6039 | ret = tracefs_create_file(name, mode, parent, data, fops); |
6019 | if (!ret) | 6040 | if (!ret) |
6020 | pr_warning("Could not create debugfs '%s' entry\n", name); | 6041 | pr_warning("Could not create tracefs '%s' entry\n", name); |
6021 | 6042 | ||
6022 | return ret; | 6043 | return ret; |
6023 | } | 6044 | } |
@@ -6034,9 +6055,9 @@ static struct dentry *trace_options_init_dentry(struct trace_array *tr) | |||
6034 | if (IS_ERR(d_tracer)) | 6055 | if (IS_ERR(d_tracer)) |
6035 | return NULL; | 6056 | return NULL; |
6036 | 6057 | ||
6037 | tr->options = debugfs_create_dir("options", d_tracer); | 6058 | tr->options = tracefs_create_dir("options", d_tracer); |
6038 | if (!tr->options) { | 6059 | if (!tr->options) { |
6039 | pr_warning("Could not create debugfs directory 'options'\n"); | 6060 | pr_warning("Could not create tracefs directory 'options'\n"); |
6040 | return NULL; | 6061 | return NULL; |
6041 | } | 6062 | } |
6042 | 6063 | ||
@@ -6105,7 +6126,7 @@ destroy_trace_option_files(struct trace_option_dentry *topts) | |||
6105 | return; | 6126 | return; |
6106 | 6127 | ||
6107 | for (cnt = 0; topts[cnt].opt; cnt++) | 6128 | for (cnt = 0; topts[cnt].opt; cnt++) |
6108 | debugfs_remove(topts[cnt].entry); | 6129 | tracefs_remove(topts[cnt].entry); |
6109 | 6130 | ||
6110 | kfree(topts); | 6131 | kfree(topts); |
6111 | } | 6132 | } |
@@ -6194,7 +6215,7 @@ static const struct file_operations rb_simple_fops = { | |||
6194 | struct dentry *trace_instance_dir; | 6215 | struct dentry *trace_instance_dir; |
6195 | 6216 | ||
6196 | static void | 6217 | static void |
6197 | init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer); | 6218 | init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer); |
6198 | 6219 | ||
6199 | static int | 6220 | static int |
6200 | allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size) | 6221 | allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size) |
@@ -6271,7 +6292,7 @@ static void free_trace_buffers(struct trace_array *tr) | |||
6271 | #endif | 6292 | #endif |
6272 | } | 6293 | } |
6273 | 6294 | ||
6274 | static int new_instance_create(const char *name) | 6295 | static int instance_mkdir(const char *name) |
6275 | { | 6296 | { |
6276 | struct trace_array *tr; | 6297 | struct trace_array *tr; |
6277 | int ret; | 6298 | int ret; |
@@ -6310,17 +6331,17 @@ static int new_instance_create(const char *name) | |||
6310 | if (allocate_trace_buffers(tr, trace_buf_size) < 0) | 6331 | if (allocate_trace_buffers(tr, trace_buf_size) < 0) |
6311 | goto out_free_tr; | 6332 | goto out_free_tr; |
6312 | 6333 | ||
6313 | tr->dir = debugfs_create_dir(name, trace_instance_dir); | 6334 | tr->dir = tracefs_create_dir(name, trace_instance_dir); |
6314 | if (!tr->dir) | 6335 | if (!tr->dir) |
6315 | goto out_free_tr; | 6336 | goto out_free_tr; |
6316 | 6337 | ||
6317 | ret = event_trace_add_tracer(tr->dir, tr); | 6338 | ret = event_trace_add_tracer(tr->dir, tr); |
6318 | if (ret) { | 6339 | if (ret) { |
6319 | debugfs_remove_recursive(tr->dir); | 6340 | tracefs_remove_recursive(tr->dir); |
6320 | goto out_free_tr; | 6341 | goto out_free_tr; |
6321 | } | 6342 | } |
6322 | 6343 | ||
6323 | init_tracer_debugfs(tr, tr->dir); | 6344 | init_tracer_tracefs(tr, tr->dir); |
6324 | 6345 | ||
6325 | list_add(&tr->list, &ftrace_trace_arrays); | 6346 | list_add(&tr->list, &ftrace_trace_arrays); |
6326 | 6347 | ||
@@ -6341,7 +6362,7 @@ static int new_instance_create(const char *name) | |||
6341 | 6362 | ||
6342 | } | 6363 | } |
6343 | 6364 | ||
6344 | static int instance_delete(const char *name) | 6365 | static int instance_rmdir(const char *name) |
6345 | { | 6366 | { |
6346 | struct trace_array *tr; | 6367 | struct trace_array *tr; |
6347 | int found = 0; | 6368 | int found = 0; |
@@ -6382,82 +6403,17 @@ static int instance_delete(const char *name) | |||
6382 | return ret; | 6403 | return ret; |
6383 | } | 6404 | } |
6384 | 6405 | ||
6385 | static int instance_mkdir (struct inode *inode, struct dentry *dentry, umode_t mode) | ||
6386 | { | ||
6387 | struct dentry *parent; | ||
6388 | int ret; | ||
6389 | |||
6390 | /* Paranoid: Make sure the parent is the "instances" directory */ | ||
6391 | parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); | ||
6392 | if (WARN_ON_ONCE(parent != trace_instance_dir)) | ||
6393 | return -ENOENT; | ||
6394 | |||
6395 | /* | ||
6396 | * The inode mutex is locked, but debugfs_create_dir() will also | ||
6397 | * take the mutex. As the instances directory can not be destroyed | ||
6398 | * or changed in any other way, it is safe to unlock it, and | ||
6399 | * let the dentry try. If two users try to make the same dir at | ||
6400 | * the same time, then the new_instance_create() will determine the | ||
6401 | * winner. | ||
6402 | */ | ||
6403 | mutex_unlock(&inode->i_mutex); | ||
6404 | |||
6405 | ret = new_instance_create(dentry->d_iname); | ||
6406 | |||
6407 | mutex_lock(&inode->i_mutex); | ||
6408 | |||
6409 | return ret; | ||
6410 | } | ||
6411 | |||
6412 | static int instance_rmdir(struct inode *inode, struct dentry *dentry) | ||
6413 | { | ||
6414 | struct dentry *parent; | ||
6415 | int ret; | ||
6416 | |||
6417 | /* Paranoid: Make sure the parent is the "instances" directory */ | ||
6418 | parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); | ||
6419 | if (WARN_ON_ONCE(parent != trace_instance_dir)) | ||
6420 | return -ENOENT; | ||
6421 | |||
6422 | /* The caller did a dget() on dentry */ | ||
6423 | mutex_unlock(&dentry->d_inode->i_mutex); | ||
6424 | |||
6425 | /* | ||
6426 | * The inode mutex is locked, but debugfs_create_dir() will also | ||
6427 | * take the mutex. As the instances directory can not be destroyed | ||
6428 | * or changed in any other way, it is safe to unlock it, and | ||
6429 | * let the dentry try. If two users try to make the same dir at | ||
6430 | * the same time, then the instance_delete() will determine the | ||
6431 | * winner. | ||
6432 | */ | ||
6433 | mutex_unlock(&inode->i_mutex); | ||
6434 | |||
6435 | ret = instance_delete(dentry->d_iname); | ||
6436 | |||
6437 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); | ||
6438 | mutex_lock(&dentry->d_inode->i_mutex); | ||
6439 | |||
6440 | return ret; | ||
6441 | } | ||
6442 | |||
6443 | static const struct inode_operations instance_dir_inode_operations = { | ||
6444 | .lookup = simple_lookup, | ||
6445 | .mkdir = instance_mkdir, | ||
6446 | .rmdir = instance_rmdir, | ||
6447 | }; | ||
6448 | |||
6449 | static __init void create_trace_instances(struct dentry *d_tracer) | 6406 | static __init void create_trace_instances(struct dentry *d_tracer) |
6450 | { | 6407 | { |
6451 | trace_instance_dir = debugfs_create_dir("instances", d_tracer); | 6408 | trace_instance_dir = tracefs_create_instance_dir("instances", d_tracer, |
6409 | instance_mkdir, | ||
6410 | instance_rmdir); | ||
6452 | if (WARN_ON(!trace_instance_dir)) | 6411 | if (WARN_ON(!trace_instance_dir)) |
6453 | return; | 6412 | return; |
6454 | |||
6455 | /* Hijack the dir inode operations, to allow mkdir */ | ||
6456 | trace_instance_dir->d_inode->i_op = &instance_dir_inode_operations; | ||
6457 | } | 6413 | } |
6458 | 6414 | ||
6459 | static void | 6415 | static void |
6460 | init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer) | 6416 | init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer) |
6461 | { | 6417 | { |
6462 | int cpu; | 6418 | int cpu; |
6463 | 6419 | ||
@@ -6511,10 +6467,32 @@ init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer) | |||
6511 | #endif | 6467 | #endif |
6512 | 6468 | ||
6513 | for_each_tracing_cpu(cpu) | 6469 | for_each_tracing_cpu(cpu) |
6514 | tracing_init_debugfs_percpu(tr, cpu); | 6470 | tracing_init_tracefs_percpu(tr, cpu); |
6515 | 6471 | ||
6516 | } | 6472 | } |
6517 | 6473 | ||
6474 | static struct vfsmount *trace_automount(void *ingore) | ||
6475 | { | ||
6476 | struct vfsmount *mnt; | ||
6477 | struct file_system_type *type; | ||
6478 | |||
6479 | /* | ||
6480 | * To maintain backward compatibility for tools that mount | ||
6481 | * debugfs to get to the tracing facility, tracefs is automatically | ||
6482 | * mounted to the debugfs/tracing directory. | ||
6483 | */ | ||
6484 | type = get_fs_type("tracefs"); | ||
6485 | if (!type) | ||
6486 | return NULL; | ||
6487 | mnt = vfs_kern_mount(type, 0, "tracefs", NULL); | ||
6488 | put_filesystem(type); | ||
6489 | if (IS_ERR(mnt)) | ||
6490 | return NULL; | ||
6491 | mntget(mnt); | ||
6492 | |||
6493 | return mnt; | ||
6494 | } | ||
6495 | |||
6518 | /** | 6496 | /** |
6519 | * tracing_init_dentry - initialize top level trace array | 6497 | * tracing_init_dentry - initialize top level trace array |
6520 | * | 6498 | * |
@@ -6526,23 +6504,30 @@ struct dentry *tracing_init_dentry(void) | |||
6526 | { | 6504 | { |
6527 | struct trace_array *tr = &global_trace; | 6505 | struct trace_array *tr = &global_trace; |
6528 | 6506 | ||
6507 | /* The top level trace array uses NULL as parent */ | ||
6529 | if (tr->dir) | 6508 | if (tr->dir) |
6530 | return tr->dir; | 6509 | return NULL; |
6531 | 6510 | ||
6532 | if (WARN_ON(!debugfs_initialized())) | 6511 | if (WARN_ON(!debugfs_initialized())) |
6533 | return ERR_PTR(-ENODEV); | 6512 | return ERR_PTR(-ENODEV); |
6534 | 6513 | ||
6535 | tr->dir = debugfs_create_dir("tracing", NULL); | 6514 | /* |
6536 | 6515 | * As there may still be users that expect the tracing | |
6516 | * files to exist in debugfs/tracing, we must automount | ||
6517 | * the tracefs file system there, so older tools still | ||
6518 | * work with the newer kerenl. | ||
6519 | */ | ||
6520 | tr->dir = debugfs_create_automount("tracing", NULL, | ||
6521 | trace_automount, NULL); | ||
6537 | if (!tr->dir) { | 6522 | if (!tr->dir) { |
6538 | pr_warn_once("Could not create debugfs directory 'tracing'\n"); | 6523 | pr_warn_once("Could not create debugfs directory 'tracing'\n"); |
6539 | return ERR_PTR(-ENOMEM); | 6524 | return ERR_PTR(-ENOMEM); |
6540 | } | 6525 | } |
6541 | 6526 | ||
6542 | return tr->dir; | 6527 | return NULL; |
6543 | } | 6528 | } |
6544 | 6529 | ||
6545 | static __init int tracer_init_debugfs(void) | 6530 | static __init int tracer_init_tracefs(void) |
6546 | { | 6531 | { |
6547 | struct dentry *d_tracer; | 6532 | struct dentry *d_tracer; |
6548 | 6533 | ||
@@ -6552,7 +6537,7 @@ static __init int tracer_init_debugfs(void) | |||
6552 | if (IS_ERR(d_tracer)) | 6537 | if (IS_ERR(d_tracer)) |
6553 | return 0; | 6538 | return 0; |
6554 | 6539 | ||
6555 | init_tracer_debugfs(&global_trace, d_tracer); | 6540 | init_tracer_tracefs(&global_trace, d_tracer); |
6556 | 6541 | ||
6557 | trace_create_file("tracing_thresh", 0644, d_tracer, | 6542 | trace_create_file("tracing_thresh", 0644, d_tracer, |
6558 | &global_trace, &tracing_thresh_fops); | 6543 | &global_trace, &tracing_thresh_fops); |
@@ -6575,6 +6560,10 @@ static __init int tracer_init_debugfs(void) | |||
6575 | 6560 | ||
6576 | create_trace_options_dir(&global_trace); | 6561 | create_trace_options_dir(&global_trace); |
6577 | 6562 | ||
6563 | /* If the tracer was started via cmdline, create options for it here */ | ||
6564 | if (global_trace.current_trace != &nop_trace) | ||
6565 | update_tracer_options(&global_trace, global_trace.current_trace); | ||
6566 | |||
6578 | return 0; | 6567 | return 0; |
6579 | } | 6568 | } |
6580 | 6569 | ||
@@ -6910,5 +6899,5 @@ __init static int clear_boot_tracer(void) | |||
6910 | return 0; | 6899 | return 0; |
6911 | } | 6900 | } |
6912 | 6901 | ||
6913 | fs_initcall(tracer_init_debugfs); | 6902 | fs_initcall(tracer_init_tracefs); |
6914 | late_initcall(clear_boot_tracer); | 6903 | late_initcall(clear_boot_tracer); |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index dd8205a35760..d951deddec89 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -334,7 +334,7 @@ struct tracer_flags { | |||
334 | 334 | ||
335 | 335 | ||
336 | /** | 336 | /** |
337 | * struct tracer - a specific tracer and its callbacks to interact with debugfs | 337 | * struct tracer - a specific tracer and its callbacks to interact with tracefs |
338 | * @name: the name chosen to select it on the available_tracers file | 338 | * @name: the name chosen to select it on the available_tracers file |
339 | * @init: called when one switches to this tracer (echo name > current_tracer) | 339 | * @init: called when one switches to this tracer (echo name > current_tracer) |
340 | * @reset: called when one switches to another tracer | 340 | * @reset: called when one switches to another tracer |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index db54dda10ccc..0d2e47370ee7 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/workqueue.h> | 13 | #include <linux/workqueue.h> |
14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
15 | #include <linux/kthread.h> | 15 | #include <linux/kthread.h> |
16 | #include <linux/debugfs.h> | 16 | #include <linux/tracefs.h> |
17 | #include <linux/uaccess.h> | 17 | #include <linux/uaccess.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/ctype.h> | 19 | #include <linux/ctype.h> |
@@ -480,7 +480,7 @@ static void remove_subsystem(struct ftrace_subsystem_dir *dir) | |||
480 | return; | 480 | return; |
481 | 481 | ||
482 | if (!--dir->nr_events) { | 482 | if (!--dir->nr_events) { |
483 | debugfs_remove_recursive(dir->entry); | 483 | tracefs_remove_recursive(dir->entry); |
484 | list_del(&dir->list); | 484 | list_del(&dir->list); |
485 | __put_system_dir(dir); | 485 | __put_system_dir(dir); |
486 | } | 486 | } |
@@ -499,7 +499,7 @@ static void remove_event_file_dir(struct ftrace_event_file *file) | |||
499 | } | 499 | } |
500 | spin_unlock(&dir->d_lock); | 500 | spin_unlock(&dir->d_lock); |
501 | 501 | ||
502 | debugfs_remove_recursive(dir); | 502 | tracefs_remove_recursive(dir); |
503 | } | 503 | } |
504 | 504 | ||
505 | list_del(&file->list); | 505 | list_del(&file->list); |
@@ -1526,7 +1526,7 @@ event_subsystem_dir(struct trace_array *tr, const char *name, | |||
1526 | } else | 1526 | } else |
1527 | __get_system(system); | 1527 | __get_system(system); |
1528 | 1528 | ||
1529 | dir->entry = debugfs_create_dir(name, parent); | 1529 | dir->entry = tracefs_create_dir(name, parent); |
1530 | if (!dir->entry) { | 1530 | if (!dir->entry) { |
1531 | pr_warn("Failed to create system directory %s\n", name); | 1531 | pr_warn("Failed to create system directory %s\n", name); |
1532 | __put_system(system); | 1532 | __put_system(system); |
@@ -1539,12 +1539,12 @@ event_subsystem_dir(struct trace_array *tr, const char *name, | |||
1539 | dir->subsystem = system; | 1539 | dir->subsystem = system; |
1540 | file->system = dir; | 1540 | file->system = dir; |
1541 | 1541 | ||
1542 | entry = debugfs_create_file("filter", 0644, dir->entry, dir, | 1542 | entry = tracefs_create_file("filter", 0644, dir->entry, dir, |
1543 | &ftrace_subsystem_filter_fops); | 1543 | &ftrace_subsystem_filter_fops); |
1544 | if (!entry) { | 1544 | if (!entry) { |
1545 | kfree(system->filter); | 1545 | kfree(system->filter); |
1546 | system->filter = NULL; | 1546 | system->filter = NULL; |
1547 | pr_warn("Could not create debugfs '%s/filter' entry\n", name); | 1547 | pr_warn("Could not create tracefs '%s/filter' entry\n", name); |
1548 | } | 1548 | } |
1549 | 1549 | ||
1550 | trace_create_file("enable", 0644, dir->entry, dir, | 1550 | trace_create_file("enable", 0644, dir->entry, dir, |
@@ -1585,9 +1585,9 @@ event_create_dir(struct dentry *parent, struct ftrace_event_file *file) | |||
1585 | d_events = parent; | 1585 | d_events = parent; |
1586 | 1586 | ||
1587 | name = ftrace_event_name(call); | 1587 | name = ftrace_event_name(call); |
1588 | file->dir = debugfs_create_dir(name, d_events); | 1588 | file->dir = tracefs_create_dir(name, d_events); |
1589 | if (!file->dir) { | 1589 | if (!file->dir) { |
1590 | pr_warn("Could not create debugfs '%s' directory\n", name); | 1590 | pr_warn("Could not create tracefs '%s' directory\n", name); |
1591 | return -1; | 1591 | return -1; |
1592 | } | 1592 | } |
1593 | 1593 | ||
@@ -2228,7 +2228,7 @@ static inline int register_event_cmds(void) { return 0; } | |||
2228 | /* | 2228 | /* |
2229 | * The top level array has already had its ftrace_event_file | 2229 | * The top level array has already had its ftrace_event_file |
2230 | * descriptors created in order to allow for early events to | 2230 | * descriptors created in order to allow for early events to |
2231 | * be recorded. This function is called after the debugfs has been | 2231 | * be recorded. This function is called after the tracefs has been |
2232 | * initialized, and we now have to create the files associated | 2232 | * initialized, and we now have to create the files associated |
2233 | * to the events. | 2233 | * to the events. |
2234 | */ | 2234 | */ |
@@ -2311,16 +2311,16 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr) | |||
2311 | struct dentry *d_events; | 2311 | struct dentry *d_events; |
2312 | struct dentry *entry; | 2312 | struct dentry *entry; |
2313 | 2313 | ||
2314 | entry = debugfs_create_file("set_event", 0644, parent, | 2314 | entry = tracefs_create_file("set_event", 0644, parent, |
2315 | tr, &ftrace_set_event_fops); | 2315 | tr, &ftrace_set_event_fops); |
2316 | if (!entry) { | 2316 | if (!entry) { |
2317 | pr_warn("Could not create debugfs 'set_event' entry\n"); | 2317 | pr_warn("Could not create tracefs 'set_event' entry\n"); |
2318 | return -ENOMEM; | 2318 | return -ENOMEM; |
2319 | } | 2319 | } |
2320 | 2320 | ||
2321 | d_events = debugfs_create_dir("events", parent); | 2321 | d_events = tracefs_create_dir("events", parent); |
2322 | if (!d_events) { | 2322 | if (!d_events) { |
2323 | pr_warn("Could not create debugfs 'events' directory\n"); | 2323 | pr_warn("Could not create tracefs 'events' directory\n"); |
2324 | return -ENOMEM; | 2324 | return -ENOMEM; |
2325 | } | 2325 | } |
2326 | 2326 | ||
@@ -2412,7 +2412,7 @@ int event_trace_del_tracer(struct trace_array *tr) | |||
2412 | 2412 | ||
2413 | down_write(&trace_event_sem); | 2413 | down_write(&trace_event_sem); |
2414 | __trace_remove_event_dirs(tr); | 2414 | __trace_remove_event_dirs(tr); |
2415 | debugfs_remove_recursive(tr->event_dir); | 2415 | tracefs_remove_recursive(tr->event_dir); |
2416 | up_write(&trace_event_sem); | 2416 | up_write(&trace_event_sem); |
2417 | 2417 | ||
2418 | tr->event_dir = NULL; | 2418 | tr->event_dir = NULL; |
@@ -2534,10 +2534,10 @@ static __init int event_trace_init(void) | |||
2534 | if (IS_ERR(d_tracer)) | 2534 | if (IS_ERR(d_tracer)) |
2535 | return 0; | 2535 | return 0; |
2536 | 2536 | ||
2537 | entry = debugfs_create_file("available_events", 0444, d_tracer, | 2537 | entry = tracefs_create_file("available_events", 0444, d_tracer, |
2538 | tr, &ftrace_avail_fops); | 2538 | tr, &ftrace_avail_fops); |
2539 | if (!entry) | 2539 | if (!entry) |
2540 | pr_warn("Could not create debugfs 'available_events' entry\n"); | 2540 | pr_warn("Could not create tracefs 'available_events' entry\n"); |
2541 | 2541 | ||
2542 | if (trace_define_common_fields()) | 2542 | if (trace_define_common_fields()) |
2543 | pr_warn("tracing: Failed to allocate common fields"); | 2543 | pr_warn("tracing: Failed to allocate common fields"); |
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 2d25ad1526bb..9cfea4c6d314 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c | |||
@@ -6,7 +6,6 @@ | |||
6 | * is Copyright (c) Steven Rostedt <srostedt@redhat.com> | 6 | * is Copyright (c) Steven Rostedt <srostedt@redhat.com> |
7 | * | 7 | * |
8 | */ | 8 | */ |
9 | #include <linux/debugfs.h> | ||
10 | #include <linux/uaccess.h> | 9 | #include <linux/uaccess.h> |
11 | #include <linux/ftrace.h> | 10 | #include <linux/ftrace.h> |
12 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
@@ -151,7 +150,7 @@ ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth, | |||
151 | * The curr_ret_stack is initialized to -1 and get increased | 150 | * The curr_ret_stack is initialized to -1 and get increased |
152 | * in this function. So it can be less than -1 only if it was | 151 | * in this function. So it can be less than -1 only if it was |
153 | * filtered out via ftrace_graph_notrace_addr() which can be | 152 | * filtered out via ftrace_graph_notrace_addr() which can be |
154 | * set from set_graph_notrace file in debugfs by user. | 153 | * set from set_graph_notrace file in tracefs by user. |
155 | */ | 154 | */ |
156 | if (current->curr_ret_stack < -1) | 155 | if (current->curr_ret_stack < -1) |
157 | return -EBUSY; | 156 | return -EBUSY; |
@@ -1432,7 +1431,7 @@ static const struct file_operations graph_depth_fops = { | |||
1432 | .llseek = generic_file_llseek, | 1431 | .llseek = generic_file_llseek, |
1433 | }; | 1432 | }; |
1434 | 1433 | ||
1435 | static __init int init_graph_debugfs(void) | 1434 | static __init int init_graph_tracefs(void) |
1436 | { | 1435 | { |
1437 | struct dentry *d_tracer; | 1436 | struct dentry *d_tracer; |
1438 | 1437 | ||
@@ -1445,7 +1444,7 @@ static __init int init_graph_debugfs(void) | |||
1445 | 1444 | ||
1446 | return 0; | 1445 | return 0; |
1447 | } | 1446 | } |
1448 | fs_initcall(init_graph_debugfs); | 1447 | fs_initcall(init_graph_tracefs); |
1449 | 1448 | ||
1450 | static __init int init_graph_trace(void) | 1449 | static __init int init_graph_trace(void) |
1451 | { | 1450 | { |
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index d73f565b4e06..ed998fbf09ce 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -1310,7 +1310,7 @@ static int unregister_kprobe_event(struct trace_kprobe *tk) | |||
1310 | return ret; | 1310 | return ret; |
1311 | } | 1311 | } |
1312 | 1312 | ||
1313 | /* Make a debugfs interface for controlling probe points */ | 1313 | /* Make a tracefs interface for controlling probe points */ |
1314 | static __init int init_kprobe_trace(void) | 1314 | static __init int init_kprobe_trace(void) |
1315 | { | 1315 | { |
1316 | struct dentry *d_tracer; | 1316 | struct dentry *d_tracer; |
@@ -1323,20 +1323,20 @@ static __init int init_kprobe_trace(void) | |||
1323 | if (IS_ERR(d_tracer)) | 1323 | if (IS_ERR(d_tracer)) |
1324 | return 0; | 1324 | return 0; |
1325 | 1325 | ||
1326 | entry = debugfs_create_file("kprobe_events", 0644, d_tracer, | 1326 | entry = tracefs_create_file("kprobe_events", 0644, d_tracer, |
1327 | NULL, &kprobe_events_ops); | 1327 | NULL, &kprobe_events_ops); |
1328 | 1328 | ||
1329 | /* Event list interface */ | 1329 | /* Event list interface */ |
1330 | if (!entry) | 1330 | if (!entry) |
1331 | pr_warning("Could not create debugfs " | 1331 | pr_warning("Could not create tracefs " |
1332 | "'kprobe_events' entry\n"); | 1332 | "'kprobe_events' entry\n"); |
1333 | 1333 | ||
1334 | /* Profile interface */ | 1334 | /* Profile interface */ |
1335 | entry = debugfs_create_file("kprobe_profile", 0444, d_tracer, | 1335 | entry = tracefs_create_file("kprobe_profile", 0444, d_tracer, |
1336 | NULL, &kprobe_profile_ops); | 1336 | NULL, &kprobe_profile_ops); |
1337 | 1337 | ||
1338 | if (!entry) | 1338 | if (!entry) |
1339 | pr_warning("Could not create debugfs " | 1339 | pr_warning("Could not create tracefs " |
1340 | "'kprobe_profile' entry\n"); | 1340 | "'kprobe_profile' entry\n"); |
1341 | return 0; | 1341 | return 0; |
1342 | } | 1342 | } |
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 4f815fbce16d..19aff635841a 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/seq_file.h> | 25 | #include <linux/seq_file.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/smp.h> | 27 | #include <linux/smp.h> |
28 | #include <linux/debugfs.h> | 28 | #include <linux/tracefs.h> |
29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
30 | #include <linux/string.h> | 30 | #include <linux/string.h> |
31 | #include <linux/ctype.h> | 31 | #include <linux/ctype.h> |
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c index 75e19e86c954..6cf935316769 100644 --- a/kernel/trace/trace_stat.c +++ b/kernel/trace/trace_stat.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <linux/list.h> | 12 | #include <linux/list.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/rbtree.h> | 14 | #include <linux/rbtree.h> |
15 | #include <linux/debugfs.h> | 15 | #include <linux/tracefs.h> |
16 | #include "trace_stat.h" | 16 | #include "trace_stat.h" |
17 | #include "trace.h" | 17 | #include "trace.h" |
18 | 18 | ||
@@ -65,7 +65,7 @@ static void reset_stat_session(struct stat_session *session) | |||
65 | 65 | ||
66 | static void destroy_session(struct stat_session *session) | 66 | static void destroy_session(struct stat_session *session) |
67 | { | 67 | { |
68 | debugfs_remove(session->file); | 68 | tracefs_remove(session->file); |
69 | __reset_stat_session(session); | 69 | __reset_stat_session(session); |
70 | mutex_destroy(&session->stat_mutex); | 70 | mutex_destroy(&session->stat_mutex); |
71 | kfree(session); | 71 | kfree(session); |
@@ -279,9 +279,9 @@ static int tracing_stat_init(void) | |||
279 | if (IS_ERR(d_tracing)) | 279 | if (IS_ERR(d_tracing)) |
280 | return 0; | 280 | return 0; |
281 | 281 | ||
282 | stat_dir = debugfs_create_dir("trace_stat", d_tracing); | 282 | stat_dir = tracefs_create_dir("trace_stat", d_tracing); |
283 | if (!stat_dir) | 283 | if (!stat_dir) |
284 | pr_warning("Could not create debugfs " | 284 | pr_warning("Could not create tracefs " |
285 | "'trace_stat' entry\n"); | 285 | "'trace_stat' entry\n"); |
286 | return 0; | 286 | return 0; |
287 | } | 287 | } |
@@ -291,7 +291,7 @@ static int init_stat_file(struct stat_session *session) | |||
291 | if (!stat_dir && tracing_stat_init()) | 291 | if (!stat_dir && tracing_stat_init()) |
292 | return -ENODEV; | 292 | return -ENODEV; |
293 | 293 | ||
294 | session->file = debugfs_create_file(session->ts->name, 0644, | 294 | session->file = tracefs_create_file(session->ts->name, 0644, |
295 | stat_dir, | 295 | stat_dir, |
296 | session, &tracing_stat_fops); | 296 | session, &tracing_stat_fops); |
297 | if (!session->file) | 297 | if (!session->file) |