... 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@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to