]> git.ipfire.org Git - people/ms/linux.git/blobdiff - kernel/trace/ftrace.c
Merge tag 'trace-v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[people/ms/linux.git] / kernel / trace / ftrace.c
index c5088c76a108f911330a0cb5e0a5c4d6aa2026c8..e750fe141a6063547c0dda2432dc6cfceec9879a 100644 (file)
@@ -88,7 +88,7 @@ struct ftrace_ops ftrace_list_end __read_mostly = {
 
 /* ftrace_enabled is a method to turn ftrace on or off */
 int ftrace_enabled __read_mostly;
-static int last_ftrace_enabled;
+static int __maybe_unused last_ftrace_enabled;
 
 /* Current function tracing op */
 struct ftrace_ops *function_trace_op __read_mostly = &ftrace_list_end;
@@ -3056,40 +3056,6 @@ int ftrace_shutdown(struct ftrace_ops *ops, int command)
        return 0;
 }
 
-static void ftrace_startup_sysctl(void)
-{
-       int command;
-
-       if (unlikely(ftrace_disabled))
-               return;
-
-       /* Force update next time */
-       saved_ftrace_func = NULL;
-       /* ftrace_start_up is true if we want ftrace running */
-       if (ftrace_start_up) {
-               command = FTRACE_UPDATE_CALLS;
-               if (ftrace_graph_active)
-                       command |= FTRACE_START_FUNC_RET;
-               ftrace_startup_enable(command);
-       }
-}
-
-static void ftrace_shutdown_sysctl(void)
-{
-       int command;
-
-       if (unlikely(ftrace_disabled))
-               return;
-
-       /* ftrace_start_up is true if ftrace is running */
-       if (ftrace_start_up) {
-               command = FTRACE_DISABLE_CALLS;
-               if (ftrace_graph_active)
-                       command |= FTRACE_STOP_FUNC_RET;
-               ftrace_run_update_code(command);
-       }
-}
-
 static u64             ftrace_update_time;
 unsigned long          ftrace_update_tot_cnt;
 unsigned long          ftrace_number_of_pages;
@@ -7405,9 +7371,6 @@ core_initcall(ftrace_nodyn_init);
 static inline int ftrace_init_dyn_tracefs(struct dentry *d_tracer) { return 0; }
 static inline void ftrace_startup_all(int command) { }
 
-# define ftrace_startup_sysctl()       do { } while (0)
-# define ftrace_shutdown_sysctl()      do { } while (0)
-
 static void ftrace_update_trampoline(struct ftrace_ops *ops)
 {
 }
@@ -7558,9 +7521,9 @@ ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops)
 
 static void
 ftrace_filter_pid_sched_switch_probe(void *data, bool preempt,
-                                    unsigned int prev_state,
                                     struct task_struct *prev,
-                                    struct task_struct *next)
+                                    struct task_struct *next,
+                                    unsigned int prev_state)
 {
        struct trace_array *tr = data;
        struct trace_pid_list *pid_list;
@@ -8047,6 +8010,109 @@ int unregister_ftrace_function(struct ftrace_ops *ops)
 }
 EXPORT_SYMBOL_GPL(unregister_ftrace_function);
 
+static int symbols_cmp(const void *a, const void *b)
+{
+       const char **str_a = (const char **) a;
+       const char **str_b = (const char **) b;
+
+       return strcmp(*str_a, *str_b);
+}
+
+struct kallsyms_data {
+       unsigned long *addrs;
+       const char **syms;
+       size_t cnt;
+       size_t found;
+};
+
+static int kallsyms_callback(void *data, const char *name,
+                            struct module *mod, unsigned long addr)
+{
+       struct kallsyms_data *args = data;
+
+       if (!bsearch(&name, args->syms, args->cnt, sizeof(*args->syms), symbols_cmp))
+               return 0;
+
+       addr = ftrace_location(addr);
+       if (!addr)
+               return 0;
+
+       args->addrs[args->found++] = addr;
+       return args->found == args->cnt ? 1 : 0;
+}
+
+/**
+ * ftrace_lookup_symbols - Lookup addresses for array of symbols
+ *
+ * @sorted_syms: array of symbols pointers symbols to resolve,
+ * must be alphabetically sorted
+ * @cnt: number of symbols/addresses in @syms/@addrs arrays
+ * @addrs: array for storing resulting addresses
+ *
+ * This function looks up addresses for array of symbols provided in
+ * @syms array (must be alphabetically sorted) and stores them in
+ * @addrs array, which needs to be big enough to store at least @cnt
+ * addresses.
+ *
+ * This function returns 0 if all provided symbols are found,
+ * -ESRCH otherwise.
+ */
+int ftrace_lookup_symbols(const char **sorted_syms, size_t cnt, unsigned long *addrs)
+{
+       struct kallsyms_data args;
+       int err;
+
+       args.addrs = addrs;
+       args.syms = sorted_syms;
+       args.cnt = cnt;
+       args.found = 0;
+       err = kallsyms_on_each_symbol(kallsyms_callback, &args);
+       if (err < 0)
+               return err;
+       return args.found == args.cnt ? 0 : -ESRCH;
+}
+
+#ifdef CONFIG_SYSCTL
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+static void ftrace_startup_sysctl(void)
+{
+       int command;
+
+       if (unlikely(ftrace_disabled))
+               return;
+
+       /* Force update next time */
+       saved_ftrace_func = NULL;
+       /* ftrace_start_up is true if we want ftrace running */
+       if (ftrace_start_up) {
+               command = FTRACE_UPDATE_CALLS;
+               if (ftrace_graph_active)
+                       command |= FTRACE_START_FUNC_RET;
+               ftrace_startup_enable(command);
+       }
+}
+
+static void ftrace_shutdown_sysctl(void)
+{
+       int command;
+
+       if (unlikely(ftrace_disabled))
+               return;
+
+       /* ftrace_start_up is true if ftrace is running */
+       if (ftrace_start_up) {
+               command = FTRACE_DISABLE_CALLS;
+               if (ftrace_graph_active)
+                       command |= FTRACE_STOP_FUNC_RET;
+               ftrace_run_update_code(command);
+       }
+}
+#else
+# define ftrace_startup_sysctl()       do { } while (0)
+# define ftrace_shutdown_sysctl()      do { } while (0)
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
 static bool is_permanent_ops_registered(void)
 {
        struct ftrace_ops *op;
@@ -8059,7 +8125,7 @@ static bool is_permanent_ops_registered(void)
        return false;
 }
 
-int
+static int
 ftrace_enable_sysctl(struct ctl_table *table, int write,
                     void *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -8102,3 +8168,22 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
        mutex_unlock(&ftrace_lock);
        return ret;
 }
+
+static struct ctl_table ftrace_sysctls[] = {
+       {
+               .procname       = "ftrace_enabled",
+               .data           = &ftrace_enabled,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = ftrace_enable_sysctl,
+       },
+       {}
+};
+
+static int __init ftrace_sysctl_init(void)
+{
+       register_sysctl_init("kernel", ftrace_sysctls);
+       return 0;
+}
+late_initcall(ftrace_sysctl_init);
+#endif