Merge tag 'trace-v4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 13 Jan 2016 04:04:15 +0000 (20:04 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 13 Jan 2016 04:04:15 +0000 (20:04 -0800)
Pull tracing updates from Steven Rostedt:
 "Not much new with tracing for this release.  Mostly just clean ups and
  minor fixes.

  Here's what else is new:

   - A new TRACE_EVENT_FN_COND macro, combining both _FN and _COND for
     those that want both.

   - New selftest to test the instance create and delete

   - Better debug output when ftrace fails"

* tag 'trace-v4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: (24 commits)
  ftrace: Fix the race between ftrace and insmod
  ftrace: Add infrastructure for delayed enabling of module functions
  x86: ftrace: Fix the comments for ftrace_modify_code_direct()
  tracing: Fix comment to use tracing_on over tracing_enable
  metag: ftrace: Fix the comments for ftrace_modify_code
  sh: ftrace: Fix the comments for ftrace_modify_code()
  ia64: ftrace: Fix the comments for ftrace_modify_code()
  ftrace: Clean up ftrace_module_init() code
  ftrace: Join functions ftrace_module_init() and ftrace_init_module()
  tracing: Introduce TRACE_EVENT_FN_COND macro
  tracing: Use seq_buf_used() in seq_buf_to_user() instead of len
  bpf: Constify bpf_verifier_ops structure
  ftrace: Have ftrace_ops_get_func() handle RCU and PER_CPU flags too
  ftrace: Remove use of control list and ops
  ftrace: Fix output of enabled_functions for showing tramp
  ftrace: Fix a typo in comment
  ftrace: Show all tramps registered to a record on ftrace_bug()
  ftrace: Add variable ftrace_expected for archs to show expected code
  ftrace: Add new type to distinguish what kind of ftrace_bug()
  tracing: Update cond flag when enabling or disabling a trigger
  ...

1  2 
include/linux/ftrace.h
include/linux/tracepoint.h
kernel/trace/trace_event_perf.c
kernel/trace/trace_events_trigger.c

diff --combined include/linux/ftrace.h
@@@ -76,8 -76,8 +76,8 @@@ ftrace_func_t ftrace_ops_get_func(struc
   * ENABLED - set/unset when ftrace_ops is registered/unregistered
   * DYNAMIC - set when ftrace_ops is registered to denote dynamically
   *           allocated ftrace_ops which need special care
-  * CONTROL - set manualy by ftrace_ops user to denote the ftrace_ops
-  *           could be controled by following calls:
+  * PER_CPU - set manualy by ftrace_ops user to denote the ftrace_ops
+  *           could be controlled by following calls:
   *             ftrace_function_local_enable
   *             ftrace_function_local_disable
   * SAVE_REGS - The ftrace_ops wants regs saved at each function called
  enum {
        FTRACE_OPS_FL_ENABLED                   = 1 << 0,
        FTRACE_OPS_FL_DYNAMIC                   = 1 << 1,
-       FTRACE_OPS_FL_CONTROL                   = 1 << 2,
+       FTRACE_OPS_FL_PER_CPU                   = 1 << 2,
        FTRACE_OPS_FL_SAVE_REGS                 = 1 << 3,
        FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED    = 1 << 4,
        FTRACE_OPS_FL_RECURSION_SAFE            = 1 << 5,
        FTRACE_OPS_FL_ALLOC_TRAMP               = 1 << 12,
        FTRACE_OPS_FL_IPMODIFY                  = 1 << 13,
        FTRACE_OPS_FL_PID                       = 1 << 14,
+       FTRACE_OPS_FL_RCU                       = 1 << 15,
  };
  
  #ifdef CONFIG_DYNAMIC_FTRACE
@@@ -146,11 -147,11 +147,11 @@@ struct ftrace_ops_hash 
  #endif
  
  /*
-  * Note, ftrace_ops can be referenced outside of RCU protection.
-  * (Although, for perf, the control ops prevent that). If ftrace_ops is
-  * allocated and not part of kernel core data, the unregistering of it will
-  * perform a scheduling on all CPUs to make sure that there are no more users.
-  * Depending on the load of the system that may take a bit of time.
+  * Note, ftrace_ops can be referenced outside of RCU protection, unless
+  * the RCU flag is set. If ftrace_ops is allocated and not part of kernel
+  * core data, the unregistering of it will perform a scheduling on all CPUs
+  * to make sure that there are no more users. Depending on the load of the
+  * system that may take a bit of time.
   *
   * Any private data added must also take care not to be freed and if private
   * data is added to a ftrace_ops that is in core code, the user of the
@@@ -196,34 -197,34 +197,34 @@@ int unregister_ftrace_function(struct f
  void clear_ftrace_function(void);
  
  /**
-  * ftrace_function_local_enable - enable controlled ftrace_ops on current cpu
+  * ftrace_function_local_enable - enable ftrace_ops on current cpu
   *
   * This function enables tracing on current cpu by decreasing
   * the per cpu control variable.
   * It must be called with preemption disabled and only on ftrace_ops
-  * registered with FTRACE_OPS_FL_CONTROL. If called without preemption
+  * registered with FTRACE_OPS_FL_PER_CPU. If called without preemption
   * disabled, this_cpu_ptr will complain when CONFIG_DEBUG_PREEMPT is enabled.
   */
  static inline void ftrace_function_local_enable(struct ftrace_ops *ops)
  {
-       if (WARN_ON_ONCE(!(ops->flags & FTRACE_OPS_FL_CONTROL)))
+       if (WARN_ON_ONCE(!(ops->flags & FTRACE_OPS_FL_PER_CPU)))
                return;
  
        (*this_cpu_ptr(ops->disabled))--;
  }
  
  /**
-  * ftrace_function_local_disable - enable controlled ftrace_ops on current cpu
+  * ftrace_function_local_disable - disable ftrace_ops on current cpu
   *
-  * This function enables tracing on current cpu by decreasing
+  * This function disables tracing on current cpu by increasing
   * the per cpu control variable.
   * It must be called with preemption disabled and only on ftrace_ops
-  * registered with FTRACE_OPS_FL_CONTROL. If called without preemption
+  * registered with FTRACE_OPS_FL_PER_CPU. If called without preemption
   * disabled, this_cpu_ptr will complain when CONFIG_DEBUG_PREEMPT is enabled.
   */
  static inline void ftrace_function_local_disable(struct ftrace_ops *ops)
  {
-       if (WARN_ON_ONCE(!(ops->flags & FTRACE_OPS_FL_CONTROL)))
+       if (WARN_ON_ONCE(!(ops->flags & FTRACE_OPS_FL_PER_CPU)))
                return;
  
        (*this_cpu_ptr(ops->disabled))++;
   *
   * This function returns value of ftrace_ops::disabled on current cpu.
   * It must be called with preemption disabled and only on ftrace_ops
-  * registered with FTRACE_OPS_FL_CONTROL. If called without preemption
+  * registered with FTRACE_OPS_FL_PER_CPU. If called without preemption
   * disabled, this_cpu_ptr will complain when CONFIG_DEBUG_PREEMPT is enabled.
   */
  static inline int ftrace_function_local_disabled(struct ftrace_ops *ops)
  {
-       WARN_ON_ONCE(!(ops->flags & FTRACE_OPS_FL_CONTROL));
+       WARN_ON_ONCE(!(ops->flags & FTRACE_OPS_FL_PER_CPU));
        return *this_cpu_ptr(ops->disabled);
  }
  
@@@ -296,6 -297,21 +297,21 @@@ int ftrace_arch_code_modify_post_proces
  
  struct dyn_ftrace;
  
+ enum ftrace_bug_type {
+       FTRACE_BUG_UNKNOWN,
+       FTRACE_BUG_INIT,
+       FTRACE_BUG_NOP,
+       FTRACE_BUG_CALL,
+       FTRACE_BUG_UPDATE,
+ };
+ extern enum ftrace_bug_type ftrace_bug_type;
+ /*
+  * Archs can set this to point to a variable that holds the value that was
+  * expected at the call site before calling ftrace_bug().
+  */
+ extern const void *ftrace_expected;
  void ftrace_bug(int err, struct dyn_ftrace *rec);
  
  struct seq_file;
@@@ -341,6 -357,7 +357,7 @@@ bool is_ftrace_trampoline(unsigned lon
   *  REGS    - the record wants the function to save regs
   *  REGS_EN - the function is set up to save regs.
   *  IPMODIFY - the record allows for the IP address to be changed.
+  *  DISABLED - the record is not ready to be touched yet
   *
   * When a new ftrace_ops is registered and wants a function to save
   * pt_regs, the rec->flag REGS is set. When the function has been
@@@ -355,10 -372,11 +372,11 @@@ enum 
        FTRACE_FL_TRAMP         = (1UL << 28),
        FTRACE_FL_TRAMP_EN      = (1UL << 27),
        FTRACE_FL_IPMODIFY      = (1UL << 26),
+       FTRACE_FL_DISABLED      = (1UL << 25),
  };
  
- #define FTRACE_REF_MAX_SHIFT  26
- #define FTRACE_FL_BITS                6
+ #define FTRACE_REF_MAX_SHIFT  25
+ #define FTRACE_FL_BITS                7
  #define FTRACE_FL_MASKED_BITS ((1UL << FTRACE_FL_BITS) - 1)
  #define FTRACE_FL_MASK                (FTRACE_FL_MASKED_BITS << FTRACE_REF_MAX_SHIFT)
  #define FTRACE_REF_MAX                ((1UL << FTRACE_REF_MAX_SHIFT) - 1)
@@@ -586,7 -604,6 +604,7 @@@ extern int ftrace_arch_read_dyn_info(ch
  
  extern int skip_trace(unsigned long ip);
  extern void ftrace_module_init(struct module *mod);
 +extern void ftrace_release_mod(struct module *mod);
  
  extern void ftrace_disable_daemon(void);
  extern void ftrace_enable_daemon(void);
  #include <linux/errno.h>
  #include <linux/types.h>
  #include <linux/rcupdate.h>
 -#include <linux/static_key.h>
 +#include <linux/tracepoint-defs.h>
  
  struct module;
  struct tracepoint;
  struct notifier_block;
  
 -struct tracepoint_func {
 -      void *func;
 -      void *data;
 -      int prio;
 -};
 -
 -struct tracepoint {
 -      const char *name;               /* Tracepoint name */
 -      struct static_key key;
 -      void (*regfunc)(void);
 -      void (*unregfunc)(void);
 -      struct tracepoint_func __rcu *funcs;
 -};
 -
  struct trace_enum_map {
        const char              *system;
        const char              *enum_string;
@@@ -157,8 -171,8 +157,8 @@@ extern void syscall_unregfunc(void)
                                TP_PROTO(data_proto),                   \
                                TP_ARGS(data_args),                     \
                                TP_CONDITION(cond),                     \
 -                              rcu_irq_enter(),                        \
 -                              rcu_irq_exit());                        \
 +                              rcu_irq_enter_irqson(),                 \
 +                              rcu_irq_exit_irqson());                 \
        }
  #else
  #define __DECLARE_TRACE_RCU(name, proto, args, cond, data_proto, data_args)
  #define TRACE_EVENT_FN(name, proto, args, struct,             \
                assign, print, reg, unreg)                      \
        DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
+ #define TRACE_EVENT_FN_COND(name, proto, args, cond, struct,          \
+               assign, print, reg, unreg)                      \
+       DECLARE_TRACE_CONDITION(name, PARAMS(proto),    \
+                       PARAMS(args), PARAMS(cond))
  #define TRACE_EVENT_CONDITION(name, proto, args, cond,                \
                              struct, assign, print)            \
        DECLARE_TRACE_CONDITION(name, PARAMS(proto),            \
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * trace event based perf event profiling/tracing
   *
 - * Copyright (C) 2009 Red Hat Inc, Peter Zijlstra <pzijlstr@redhat.com>
 + * Copyright (C) 2009 Red Hat Inc, Peter Zijlstra
   * Copyright (C) 2009-2010 Frederic Weisbecker <fweisbec@gmail.com>
   */
  
@@@ -334,7 -334,7 +334,7 @@@ static int perf_ftrace_function_registe
  {
        struct ftrace_ops *ops = &event->ftrace_ops;
  
-       ops->flags |= FTRACE_OPS_FL_CONTROL;
+       ops->flags |= FTRACE_OPS_FL_PER_CPU | FTRACE_OPS_FL_RCU;
        ops->func = perf_ftrace_function_call;
        return register_ftrace_function(ops);
  }
@@@ -237,23 -237,28 +237,23 @@@ static ssize_t event_trigger_regex_writ
        if (cnt >= PAGE_SIZE)
                return -EINVAL;
  
 -      buf = (char *)__get_free_page(GFP_TEMPORARY);
 -      if (!buf)
 -              return -ENOMEM;
 +      buf = memdup_user_nul(ubuf, cnt);
 +      if (IS_ERR(buf))
 +              return PTR_ERR(buf);
  
 -      if (copy_from_user(buf, ubuf, cnt)) {
 -              free_page((unsigned long)buf);
 -              return -EFAULT;
 -      }
 -      buf[cnt] = '\0';
        strim(buf);
  
        mutex_lock(&event_mutex);
        event_file = event_file_data(file);
        if (unlikely(!event_file)) {
                mutex_unlock(&event_mutex);
 -              free_page((unsigned long)buf);
 +              kfree(buf);
                return -ENODEV;
        }
        ret = trigger_process_regex(event_file, buf);
        mutex_unlock(&event_mutex);
  
 -      free_page((unsigned long)buf);
 +      kfree(buf);
        if (ret < 0)
                goto out;
  
@@@ -538,11 -543,12 +538,12 @@@ static int register_trigger(char *glob
        list_add_rcu(&data->list, &file->triggers);
        ret++;
  
+       update_cond_flag(file);
        if (trace_event_trigger_enable_disable(file, 1) < 0) {
                list_del_rcu(&data->list);
+               update_cond_flag(file);
                ret--;
        }
-       update_cond_flag(file);
  out:
        return ret;
  }
@@@ -570,8 -576,8 +571,8 @@@ static void unregister_trigger(char *gl
                if (data->cmd_ops->trigger_type == test->cmd_ops->trigger_type) {
                        unregistered = true;
                        list_del_rcu(&data->list);
-                       update_cond_flag(file);
                        trace_event_trigger_enable_disable(file, 0);
+                       update_cond_flag(file);
                        break;
                }
        }
@@@ -1314,11 -1320,12 +1315,12 @@@ static int event_enable_register_trigge
        list_add_rcu(&data->list, &file->triggers);
        ret++;
  
+       update_cond_flag(file);
        if (trace_event_trigger_enable_disable(file, 1) < 0) {
                list_del_rcu(&data->list);
+               update_cond_flag(file);
                ret--;
        }
-       update_cond_flag(file);
  out:
        return ret;
  }
@@@ -1339,8 -1346,8 +1341,8 @@@ static void event_enable_unregister_tri
                    (enable_data->file == test_enable_data->file)) {
                        unregistered = true;
                        list_del_rcu(&data->list);
-                       update_cond_flag(file);
                        trace_event_trigger_enable_disable(file, 0);
+                       update_cond_flag(file);
                        break;
                }
        }