Merge remote-tracking branch 'ftrace/for-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Tue, 13 Sep 2016 02:05:37 +0000 (12:05 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Tue, 13 Sep 2016 02:05:37 +0000 (12:05 +1000)
1  2 
arch/sh/kernel/ftrace.c
include/linux/ftrace.h
kernel/trace/Kconfig
kernel/trace/trace.c
kernel/trace/trace_functions_graph.c
kernel/trace/trace_uprobe.c

diff --combined arch/sh/kernel/ftrace.c
index 95eccd49672f40ca7f5e10f998c3226581221c29,deb9eba3a43ddc081fd051976c5904026b0261ee..53783978162e2d1c82c1f44b349f7530d650c341
@@@ -139,7 -139,7 +139,7 @@@ static void ftrace_mod_code(void
                clear_mod_flag();
  }
  
- void ftrace_nmi_enter(void)
+ void arch_ftrace_nmi_enter(void)
  {
        if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) {
                smp_rmb();
        smp_mb();
  }
  
- void ftrace_nmi_exit(void)
+ void arch_ftrace_nmi_exit(void)
  {
        /* Finish all executions before clearing nmi_running */
        smp_mb();
@@@ -382,7 -382,7 +382,7 @@@ void prepare_ftrace_return(unsigned lon
                return;
        }
  
 -      err = ftrace_push_return_trace(old, self_addr, &trace.depth, 0);
 +      err = ftrace_push_return_trace(old, self_addr, &trace.depth, 0, NULL);
        if (err == -EBUSY) {
                __raw_writel(old, parent);
                return;
diff --combined include/linux/ftrace.h
index 6f93ac46e7f0a52f6091755ebf879f14dc80c525,1e2b316d669306d3614381a3157c4fc5e10c1fd5..b3d34d3e0e7efe5d5bd55d7b05616974831c636c
@@@ -794,13 -794,10 +794,15 @@@ struct ftrace_ret_stack 
        unsigned long ret;
        unsigned long func;
        unsigned long long calltime;
+ #ifdef CONFIG_FUNCTION_PROFILER
        unsigned long long subtime;
+ #endif
 +#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
        unsigned long fp;
 +#endif
 +#ifdef HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
 +      unsigned long *retp;
 +#endif
  };
  
  /*
@@@ -812,10 -809,7 +814,10 @@@ extern void return_to_handler(void)
  
  extern int
  ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth,
 -                       unsigned long frame_pointer);
 +                       unsigned long frame_pointer, unsigned long *retp);
 +
 +unsigned long ftrace_graph_ret_addr(struct task_struct *task, int *idx,
 +                                  unsigned long ret, unsigned long *retp);
  
  /*
   * Sometimes we don't want to trace a function with the function
@@@ -878,13 -872,6 +880,13 @@@ static inline int task_curr_ret_stack(s
        return -1;
  }
  
 +static inline unsigned long
 +ftrace_graph_ret_addr(struct task_struct *task, int *idx, unsigned long ret,
 +                    unsigned long *retp)
 +{
 +      return ret;
 +}
 +
  static inline void pause_graph_tracing(void) { }
  static inline void unpause_graph_tracing(void) { }
  #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --combined kernel/trace/Kconfig
index ba3326785ca4cffcf245da527f0386b2d8c23608,72c07c2ffd797d717b482524e8d2cd5a208f24e2..2a96b063d6590f326410feaa55fbb7f817241c0c
@@@ -24,6 -24,11 +24,6 @@@ config HAVE_FUNCTION_GRAPH_TRACE
        help
          See Documentation/trace/ftrace-design.txt
  
 -config HAVE_FUNCTION_GRAPH_FP_TEST
 -      bool
 -      help
 -        See Documentation/trace/ftrace-design.txt
 -
  config HAVE_DYNAMIC_FTRACE
        bool
        help
@@@ -216,6 -221,41 +216,41 @@@ config SCHED_TRACE
          This tracer tracks the latency of the highest priority task
          to be scheduled in, starting from the point it has woken up.
  
+ config HWLAT_TRACER
+       bool "Tracer to detect hardware latencies (like SMIs)"
+       select GENERIC_TRACER
+       help
+        This tracer, when enabled will create one or more kernel threads,
+        depening on what the cpumask file is set to, which each thread
+        spinning in a loop looking for interruptions caused by
+        something other than the kernel. For example, if a
+        System Management Interrupt (SMI) takes a noticeable amount of
+        time, this tracer will detect it. This is useful for testing
+        if a system is reliable for Real Time tasks.
+        Some files are created in the tracing directory when this
+        is enabled:
+          hwlat_detector/width   - time in usecs for how long to spin for
+          hwlat_detector/window  - time in usecs between the start of each
+                                    iteration
+        A kernel thread is created that will spin with interrupts disabled
+        for "width" microseconds in every "widow" cycle. It will not spin
+        for "window - width" microseconds, where the system can
+        continue to operate.
+        The output will appear in the trace and trace_pipe files.
+        When the tracer is not running, it has no affect on the system,
+        but when it is running, it can cause the system to be
+        periodically non responsive. Do not run this tracer on a
+        production system.
+        To enable this tracer, echo in "hwlat" into the current_tracer
+        file. Every time a latency is greater than tracing_thresh, it will
+        be recorded into the ring buffer.
  config ENABLE_DEFAULT_TRACERS
        bool "Trace process context switches and events"
        depends on !GENERIC_TRACER
diff --combined kernel/trace/trace.c
index 1e2ce3b52e51fdd843995350a3dffc11c98b584e,e0d0cfc1aa2055c9adea2b8157ab8094ed37f926..6854d40213754134d5c8e21d51074e663aadee09
@@@ -1047,7 -1047,7 +1047,7 @@@ void disable_trace_on_warning(void
   *
   * Shows real state of the ring buffer if it is enabled or not.
   */
static int tracer_tracing_is_on(struct trace_array *tr)
+ int tracer_tracing_is_on(struct trace_array *tr)
  {
        if (tr->trace_buffer.buffer)
                return ring_buffer_record_is_on(tr->trace_buffer.buffer);
@@@ -4123,30 -4123,6 +4123,30 @@@ static const char readme_msg[] 
        "\t\t\t  traces\n"
  #endif
  #endif /* CONFIG_STACK_TRACER */
 +#ifdef CONFIG_KPROBE_EVENT
 +      "  kprobe_events\t\t- Add/remove/show the kernel dynamic events\n"
 +      "\t\t\t  Write into this file to define/undefine new trace events.\n"
 +#endif
 +#ifdef CONFIG_UPROBE_EVENT
 +      "  uprobe_events\t\t- Add/remove/show the userspace dynamic events\n"
 +      "\t\t\t  Write into this file to define/undefine new trace events.\n"
 +#endif
 +#if defined(CONFIG_KPROBE_EVENT) || defined(CONFIG_UPROBE_EVENT)
 +      "\t  accepts: event-definitions (one definition per line)\n"
 +      "\t   Format: p|r[:[<group>/]<event>] <place> [<args>]\n"
 +      "\t           -:[<group>/]<event>\n"
 +#ifdef CONFIG_KPROBE_EVENT
 +      "\t    place: [<module>:]<symbol>[+<offset>]|<memaddr>\n"
 +#endif
 +#ifdef CONFIG_UPROBE_EVENT
 +      "\t    place: <path>:<offset>\n"
 +#endif
 +      "\t     args: <name>=fetcharg[:type]\n"
 +      "\t fetcharg: %<register>, @<address>, @<symbol>[+|-<offset>],\n"
 +      "\t           $stack<index>, $stack, $retval, $comm\n"
 +      "\t     type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string,\n"
 +      "\t           b<bit-width>@<bit-offset>/<container-size>\n"
 +#endif
        "  events/\t\t- Directory containing all trace event subsystems:\n"
        "      enable\t\t- Write 0/1 to enable/disable tracing of all events\n"
        "  events/<system>/\t- Directory containing all trace events for <system>:\n"
@@@ -4969,7 -4945,7 +4969,7 @@@ out
        return ret;
  }
  
- #ifdef CONFIG_TRACER_MAX_TRACE
+ #if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
  
  static ssize_t
  tracing_max_lat_read(struct file *filp, char __user *ubuf,
@@@ -5891,7 -5867,7 +5891,7 @@@ static const struct file_operations tra
        .llseek         = generic_file_llseek,
  };
  
- #ifdef CONFIG_TRACER_MAX_TRACE
+ #if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
  static const struct file_operations tracing_max_lat_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_max_lat_read,
@@@ -7219,7 -7195,7 +7219,7 @@@ init_tracer_tracefs(struct trace_array 
  
        create_trace_options_dir(tr);
  
- #ifdef CONFIG_TRACER_MAX_TRACE
+ #if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
        trace_create_file("tracing_max_latency", 0644, d_tracer,
                        &tr->max_latency, &tracing_max_lat_fops);
  #endif
index 0cbe38a844fa9b57563cb650f93973b7d35e71f0,148c90f1e49b29d970977ac53bcef2ed789a072a..4e480e8704746ec85a48de6f9990a8c6ff060cd2
@@@ -119,7 -119,7 +119,7 @@@ print_graph_duration(struct trace_arra
  /* Add a function return address to the trace stack on thread info.*/
  int
  ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth,
 -                       unsigned long frame_pointer)
 +                       unsigned long frame_pointer, unsigned long *retp)
  {
        unsigned long long calltime;
        int index;
        current->ret_stack[index].ret = ret;
        current->ret_stack[index].func = func;
        current->ret_stack[index].calltime = calltime;
-       current->ret_stack[index].subtime = 0;
 +#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
        current->ret_stack[index].fp = frame_pointer;
 +#endif
 +#ifdef HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
 +      current->ret_stack[index].retp = retp;
 +#endif
        *depth = current->curr_ret_stack;
  
        return 0;
@@@ -209,7 -203,7 +208,7 @@@ ftrace_pop_return_trace(struct ftrace_g
                return;
        }
  
 -#if defined(CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST) && !defined(CC_USING_FENTRY)
 +#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
        /*
         * The arch may choose to record the frame pointer used
         * and check it here to make sure that it is what we expect it
@@@ -284,64 -278,6 +283,64 @@@ unsigned long ftrace_return_to_handler(
        return ret;
  }
  
 +/**
 + * ftrace_graph_ret_addr - convert a potentially modified stack return address
 + *                       to its original value
 + *
 + * This function can be called by stack unwinding code to convert a found stack
 + * return address ('ret') to its original value, in case the function graph
 + * tracer has modified it to be 'return_to_handler'.  If the address hasn't
 + * been modified, the unchanged value of 'ret' is returned.
 + *
 + * 'idx' is a state variable which should be initialized by the caller to zero
 + * before the first call.
 + *
 + * 'retp' is a pointer to the return address on the stack.  It's ignored if
 + * the arch doesn't have HAVE_FUNCTION_GRAPH_RET_ADDR_PTR defined.
 + */
 +#ifdef HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
 +unsigned long ftrace_graph_ret_addr(struct task_struct *task, int *idx,
 +                                  unsigned long ret, unsigned long *retp)
 +{
 +      int index = task->curr_ret_stack;
 +      int i;
 +
 +      if (ret != (unsigned long)return_to_handler)
 +              return ret;
 +
 +      if (index < -1)
 +              index += FTRACE_NOTRACE_DEPTH;
 +
 +      if (index < 0)
 +              return ret;
 +
 +      for (i = 0; i <= index; i++)
 +              if (task->ret_stack[i].retp == retp)
 +                      return task->ret_stack[i].ret;
 +
 +      return ret;
 +}
 +#else /* !HAVE_FUNCTION_GRAPH_RET_ADDR_PTR */
 +unsigned long ftrace_graph_ret_addr(struct task_struct *task, int *idx,
 +                                  unsigned long ret, unsigned long *retp)
 +{
 +      int task_idx;
 +
 +      if (ret != (unsigned long)return_to_handler)
 +              return ret;
 +
 +      task_idx = task->curr_ret_stack;
 +
 +      if (!task->ret_stack || task_idx < *idx)
 +              return ret;
 +
 +      task_idx -= *idx;
 +      (*idx)++;
 +
 +      return task->ret_stack[task_idx].ret;
 +}
 +#endif /* HAVE_FUNCTION_GRAPH_RET_ADDR_PTR */
 +
  int __trace_graph_entry(struct trace_array *tr,
                                struct ftrace_graph_ent *trace,
                                unsigned long flags,
@@@ -1183,6 -1119,11 +1182,11 @@@ print_graph_comment(struct trace_seq *s
        trace_seq_puts(s, "/* ");
  
        switch (iter->ent->type) {
+       case TRACE_BPUTS:
+               ret = trace_print_bputs_msg_only(iter);
+               if (ret != TRACE_TYPE_HANDLED)
+                       return ret;
+               break;
        case TRACE_BPRINT:
                ret = trace_print_bprintk_msg_only(iter);
                if (ret != TRACE_TYPE_HANDLED)
index 7a687320f8671c7e82ee1c5ebca6dc7d2b77380c,a74f2d9ff37956061eae2e5b6ebb6aea71e25f60..0913693caf6e037f2cd20edc0b1a3c22276d00bf
@@@ -211,10 -211,6 +211,10 @@@ static const struct fetch_type uprobes_
        ASSIGN_FETCH_TYPE(s16, u16, 1),
        ASSIGN_FETCH_TYPE(s32, u32, 1),
        ASSIGN_FETCH_TYPE(s64, u64, 1),
 +      ASSIGN_FETCH_TYPE_ALIAS(x8,  u8,  u8,  0),
 +      ASSIGN_FETCH_TYPE_ALIAS(x16, u16, u16, 0),
 +      ASSIGN_FETCH_TYPE_ALIAS(x32, u32, u32, 0),
 +      ASSIGN_FETCH_TYPE_ALIAS(x64, u64, u64, 0),
  
        ASSIGN_FETCH_TYPE_END
  };
@@@ -431,10 -427,6 +431,6 @@@ static int create_trace_uprobe(int argc
                pr_info("Probe point is not specified.\n");
                return -EINVAL;
        }
-       if (isdigit(argv[1][0])) {
-               pr_info("probe point must be have a filename.\n");
-               return -EINVAL;
-       }
        arg = strchr(argv[1], ':');
        if (!arg) {
                ret = -EINVAL;
This page took 0.0383790000000001 seconds and 5 git commands to generate.