... Explain why we want this! ... ... Explain why we make these changes ... --- include/linux/trace.h | 4 ++ kernel/trace/trace.c | 142 ++++++++++++++++++++++++++++++------------ 2 files changed, 105 insertions(+), 41 deletions(-) diff --git a/include/linux/trace.h b/include/linux/trace.h index 7fd86d3c691f..337454e859f4 100644 --- a/include/linux/trace.h +++ b/include/linux/trace.h @@ -30,8 +30,12 @@ void trace_printk_init_buffers(void); int trace_array_printk(struct trace_array *tr, unsigned long ip, const char *fmt, ...); void trace_array_put(struct trace_array *tr); +struct trace_array *trace_array_create(void); struct trace_array *trace_array_get_by_name(const char *name); int trace_array_destroy(struct trace_array *tr); + +int anon_trace_getfd(const char *name, struct trace_array *tr); + #endif /* CONFIG_TRACING */ #endif /* _LINUX_TRACE_H */ diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8f7fdc25f230..6c2286b81b4a 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -48,6 +48,7 @@ #include <linux/fsnotify.h> #include <linux/irq_work.h> #include <linux/workqueue.h> +#include <linux/anon_inodes.h> #include "trace.h" #include "trace_output.h" @@ -4140,7 +4141,7 @@ static int s_show(struct seq_file *m, void *v) */ static inline int tracing_get_cpu(struct inode *inode) { - if (inode->i_cdev) /* See trace_create_cpu_file() */ + if (inode && inode->i_cdev) /* See trace_create_cpu_file() */ return (long)inode->i_cdev - 1; return RING_BUFFER_ALL_CPUS; } @@ -5938,32 +5939,22 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf, #endif -static int tracing_open_pipe(struct inode *inode, struct file *filp) +static struct trace_iterator * +tracing_create_pipe_iter(struct trace_array *tr, struct inode *inode) { - struct trace_array *tr = inode->i_private; struct trace_iterator *iter; - int ret; - - ret = tracing_check_open_get_tr(tr); - if (ret) - return ret; - - mutex_lock(&trace_types_lock); /* create a buffer to store the information to pass to userspace */ iter = kzalloc(sizeof(*iter), GFP_KERNEL); - if (!iter) { - ret = -ENOMEM; - __trace_array_put(tr); - goto out; - } + if (!iter) + return ERR_PTR(-ENOMEM); trace_seq_init(&iter->seq); iter->trace = tr->current_trace; if (!alloc_cpumask_var(&iter->started, GFP_KERNEL)) { - ret = -ENOMEM; - goto fail; + kfree(iter); + return ERR_PTR(-ENOMEM); } /* trace pipe does not show start of buffer */ @@ -5980,6 +5971,29 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) iter->trace_buffer = &tr->trace_buffer; iter->cpu_file = tracing_get_cpu(inode); mutex_init(&iter->mutex); + + return iter; +} + +static int tracing_open_pipe(struct inode *inode, struct file *filp) +{ + struct trace_array *tr = inode->i_private; + struct trace_iterator *iter; + int ret; + + ret = tracing_check_open_get_tr(tr); + if (ret) + return ret; + + mutex_lock(&trace_types_lock); + + iter = tracing_create_pipe_iter(tr, inode); + if (IS_ERR(iter)) { + ret = PTR_ERR(iter); + __trace_array_put(tr); + goto out; + } + filp->private_data = iter; if (iter->trace->pipe_open) @@ -5991,18 +6005,12 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) out: mutex_unlock(&trace_types_lock); return ret; - -fail: - kfree(iter); - __trace_array_put(tr); - mutex_unlock(&trace_types_lock); - return ret; } static int tracing_release_pipe(struct inode *inode, struct file *file) { struct trace_iterator *iter = file->private_data; - struct trace_array *tr = inode->i_private; + struct trace_array *tr = iter->tr; mutex_lock(&trace_types_lock); @@ -7868,7 +7876,7 @@ static inline __init int register_snapshot_cmd(void) { return 0; } static struct dentry *tracing_get_dentry(struct trace_array *tr) { - if (WARN_ON(!tr->dir)) + if (!tr->dir) return ERR_PTR(-ENODEV); /* Top directory uses NULL as the parent */ @@ -8461,7 +8469,7 @@ static void update_tracer_options(struct trace_array *tr) mutex_unlock(&trace_types_lock); } -static struct trace_array *trace_array_create(const char *name) +static struct trace_array *__trace_array_create(const char *name) { struct trace_array *tr; int ret; @@ -8471,9 +8479,11 @@ static struct trace_array *trace_array_create(const char *name) if (!tr) return ERR_PTR(ret); - tr->name = kstrdup(name, GFP_KERNEL); - if (!tr->name) - goto out_free_tr; + if (name) { + tr->name = kstrdup(name, GFP_KERNEL); + if (!tr->name) + goto out_free_tr; + } if (!alloc_cpumask_var(&tr->tracing_cpumask, GFP_KERNEL)) goto out_free_tr; @@ -8496,19 +8506,22 @@ static struct trace_array *trace_array_create(const char *name) if (allocate_trace_buffers(tr, trace_buf_size) < 0) goto out_free_tr; - tr->dir = tracefs_create_dir(name, trace_instance_dir); - if (!tr->dir) - goto out_free_tr; + if (name) { + tr->dir = tracefs_create_dir(name, trace_instance_dir); + if (!tr->dir) + goto out_free_tr; - ret = event_trace_add_tracer(tr->dir, tr); - if (ret) { - tracefs_remove_recursive(tr->dir); - goto out_free_tr; + ret = event_trace_add_tracer(tr->dir, tr); + if (ret) { + tracefs_remove_recursive(tr->dir); + goto out_free_tr; + } + + init_tracer_tracefs(tr, tr->dir); } ftrace_init_trace_array(tr); - init_tracer_tracefs(tr, tr->dir); init_trace_flags_index(tr); __update_tracer_options(tr); @@ -8516,7 +8529,6 @@ static struct trace_array *trace_array_create(const char *name) tr->ref++; - return tr; out_free_tr: @@ -8528,6 +8540,12 @@ static struct trace_array *trace_array_create(const char *name) return ERR_PTR(ret); } +struct trace_array *trace_array_create(void) +{ + return __trace_array_create(NULL); +} +EXPORT_SYMBOL_GPL(trace_array_create); + static int instance_mkdir(const char *name) { struct trace_array *tr; @@ -8542,7 +8560,7 @@ static int instance_mkdir(const char *name) goto out_unlock; } - tr = trace_array_create(name); + tr = __trace_array_create(name); ret = PTR_ERR_OR_ZERO(tr); @@ -8576,7 +8594,7 @@ struct trace_array *trace_array_get_by_name(const char *name) goto out_unlock; } - tr = trace_array_create(name); + tr = __trace_array_create(name); if (IS_ERR(tr)) tr = NULL; @@ -8611,7 +8629,8 @@ static int __remove_instance(struct trace_array *tr) event_trace_del_tracer(tr); ftrace_clear_pids(tr); ftrace_destroy_function_files(tr); - tracefs_remove_recursive(tr->dir); + if (tr->dir) + tracefs_remove_recursive(tr->dir); free_trace_buffers(tr); for (i = 0; i < tr->nr_topts; i++) { @@ -9157,6 +9176,47 @@ void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) } EXPORT_SYMBOL_GPL(ftrace_dump); +int anon_trace_getfd(const char *name, struct trace_array *tr) +{ + struct trace_iterator *iter; + int ret; + + if (!tr || trace_array_get(tr) < 0) + return -ENODEV; + + mutex_lock(&trace_types_lock); + + iter = tracing_create_pipe_iter(tr, NULL); + if (IS_ERR(iter)) { + ret = PTR_ERR(iter); + __trace_array_put(tr); + goto out; + } + + ret = anon_inode_getfd(name, &tracing_pipe_fops, iter, O_CLOEXEC); + if (ret < 0) + goto fail; + + if (iter->trace->pipe_open) + iter->trace->pipe_open(iter); + + tr->current_trace->ref++; +out: + mutex_unlock(&trace_types_lock); + return ret; + +fail: + mutex_unlock(&trace_types_lock); + + free_cpumask_var(iter->started); + mutex_destroy(&iter->mutex); + kfree(iter); + + trace_array_put(tr); + return ret; +} +EXPORT_SYMBOL_GPL(anon_trace_getfd); + int trace_run_command(const char *buf, int (*createfn)(int, char **)) { char **argv; -- 2.25.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx