]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - kernel/trace/trace_probe.c
Merge branch 'for-linus-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/ibft
[linux.git] / kernel / trace / trace_probe.c
index 509a26024b4f5031e8aff6681074b569bbe0f646..dbef0d1350754c5404995811f31358bc39087400 100644 (file)
@@ -844,6 +844,7 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len,
 
 int traceprobe_set_print_fmt(struct trace_probe *tp, bool is_return)
 {
+       struct trace_event_call *call = trace_probe_event_call(tp);
        int len;
        char *print_fmt;
 
@@ -855,7 +856,7 @@ int traceprobe_set_print_fmt(struct trace_probe *tp, bool is_return)
 
        /* Second: actually write the @print_fmt */
        __set_print_fmt(tp, print_fmt, len + 1, is_return);
-       tp->call.print_fmt = print_fmt;
+       call->print_fmt = print_fmt;
 
        return 0;
 }
@@ -888,31 +889,34 @@ int traceprobe_define_arg_fields(struct trace_event_call *event_call,
 
 void trace_probe_cleanup(struct trace_probe *tp)
 {
+       struct trace_event_call *call = trace_probe_event_call(tp);
        int i;
 
        for (i = 0; i < tp->nr_args; i++)
                traceprobe_free_probe_arg(&tp->args[i]);
 
-       kfree(tp->call.class->system);
-       kfree(tp->call.name);
-       kfree(tp->call.print_fmt);
+       kfree(call->class->system);
+       kfree(call->name);
+       kfree(call->print_fmt);
 }
 
 int trace_probe_init(struct trace_probe *tp, const char *event,
                     const char *group)
 {
+       struct trace_event_call *call = trace_probe_event_call(tp);
+
        if (!event || !group)
                return -EINVAL;
 
-       tp->call.class = &tp->class;
-       tp->call.name = kstrdup(event, GFP_KERNEL);
-       if (!tp->call.name)
+       call->class = &tp->class;
+       call->name = kstrdup(event, GFP_KERNEL);
+       if (!call->name)
                return -ENOMEM;
 
        tp->class.system = kstrdup(group, GFP_KERNEL);
        if (!tp->class.system) {
-               kfree(tp->call.name);
-               tp->call.name = NULL;
+               kfree(call->name);
+               call->name = NULL;
                return -ENOMEM;
        }
        INIT_LIST_HEAD(&tp->files);
@@ -923,7 +927,7 @@ int trace_probe_init(struct trace_probe *tp, const char *event,
 
 int trace_probe_register_event_call(struct trace_probe *tp)
 {
-       struct trace_event_call *call = &tp->call;
+       struct trace_event_call *call = trace_probe_event_call(tp);
        int ret;
 
        ret = register_trace_event(&call->event);
@@ -936,3 +940,50 @@ int trace_probe_register_event_call(struct trace_probe *tp)
 
        return ret;
 }
+
+int trace_probe_add_file(struct trace_probe *tp, struct trace_event_file *file)
+{
+       struct event_file_link *link;
+
+       link = kmalloc(sizeof(*link), GFP_KERNEL);
+       if (!link)
+               return -ENOMEM;
+
+       link->file = file;
+       INIT_LIST_HEAD(&link->list);
+       list_add_tail_rcu(&link->list, &tp->files);
+       trace_probe_set_flag(tp, TP_FLAG_TRACE);
+       return 0;
+}
+
+struct event_file_link *trace_probe_get_file_link(struct trace_probe *tp,
+                                                 struct trace_event_file *file)
+{
+       struct event_file_link *link;
+
+       trace_probe_for_each_link(link, tp) {
+               if (link->file == file)
+                       return link;
+       }
+
+       return NULL;
+}
+
+int trace_probe_remove_file(struct trace_probe *tp,
+                           struct trace_event_file *file)
+{
+       struct event_file_link *link;
+
+       link = trace_probe_get_file_link(tp, file);
+       if (!link)
+               return -ENOENT;
+
+       list_del_rcu(&link->list);
+       synchronize_rcu();
+       kfree(link);
+
+       if (list_empty(&tp->files))
+               trace_probe_clear_flag(tp, TP_FLAG_TRACE);
+
+       return 0;
+}