Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 5 Dec 2009 23:30:21 +0000 (15:30 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 5 Dec 2009 23:30:21 +0000 (15:30 -0800)
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (470 commits)
  x86: Fix comments of register/stack access functions
  perf tools: Replace %m with %a in sscanf
  hw-breakpoints: Keep track of user disabled breakpoints
  tracing/syscalls: Make syscall events print callbacks static
  tracing: Add DEFINE_EVENT(), DEFINE_SINGLE_EVENT() support to docbook
  perf: Don't free perf_mmap_data until work has been done
  perf_event: Fix compile error
  perf tools: Fix _GNU_SOURCE macro related strndup() build error
  trace_syscalls: Remove unused syscall_name_to_nr()
  trace_syscalls: Simplify syscall profile
  trace_syscalls: Remove duplicate init_enter_##sname()
  trace_syscalls: Add syscall_nr field to struct syscall_metadata
  trace_syscalls: Remove enter_id exit_id
  trace_syscalls: Set event_enter_##sname->data to its metadata
  trace_syscalls: Remove unused event_syscall_enter and event_syscall_exit
  perf_event: Initialize data.period in perf_swevent_hrtimer()
  perf probe: Simplify event naming
  perf probe: Add --list option for listing current probe events
  perf probe: Add argv_split() from lib/argv_split.c
  perf probe: Move probe event utility functions to probe-event.c
  ...

1  2 
include/trace/ftrace.h
kernel/Makefile
kernel/kprobes.c
kernel/signal.c
kernel/trace/ring_buffer.c
kernel/trace/trace_export.c

diff --combined include/trace/ftrace.h
index dacb8ef6700071238a3293799f57610909c6f22f,2c9c073e45ad1662ee5f88dc80fe7aff757f3042..d1b3de9c1a714f7624956c01fb60bd22898d4c6a
  
  #include <linux/ftrace_event.h>
  
+ /*
+  * DECLARE_EVENT_CLASS can be used to add a generic function
+  * handlers for events. That is, if all events have the same
+  * parameters and just have distinct trace points.
+  * Each tracepoint can be defined with DEFINE_EVENT and that
+  * will map the DECLARE_EVENT_CLASS to the tracepoint.
+  *
+  * TRACE_EVENT is a one to one mapping between tracepoint and template.
+  */
+ #undef TRACE_EVENT
+ #define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
+       DECLARE_EVENT_CLASS(name,                              \
+                            PARAMS(proto),                    \
+                            PARAMS(args),                     \
+                            PARAMS(tstruct),                  \
+                            PARAMS(assign),                   \
+                            PARAMS(print));                   \
+       DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args));
  #undef __field
  #define __field(type, item)           type    item;
  
  #undef TP_STRUCT__entry
  #define TP_STRUCT__entry(args...) args
  
- #undef TRACE_EVENT
- #define TRACE_EVENT(name, proto, args, tstruct, assign, print)        \
-       struct ftrace_raw_##name {                              \
-               struct trace_entry      ent;                    \
-               tstruct                                         \
-               char                    __data[0];              \
-       };                                                      \
+ #undef DECLARE_EVENT_CLASS
+ #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)        \
+       struct ftrace_raw_##name {                                      \
+               struct trace_entry      ent;                            \
+               tstruct                                                 \
+               char                    __data[0];                      \
+       };
+ #undef DEFINE_EVENT
+ #define DEFINE_EVENT(template, name, proto, args)     \
        static struct ftrace_event_call event_##name
  
+ #undef DEFINE_EVENT_PRINT
+ #define DEFINE_EVENT_PRINT(template, name, proto, args, print)        \
+       DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
  #undef __cpparg
  #define __cpparg(arg...) arg
  
  #undef __string
  #define __string(item, src) __dynamic_array(char, item, -1)
  
- #undef TRACE_EVENT
- #define TRACE_EVENT(call, proto, args, tstruct, assign, print)                \
+ #undef DECLARE_EVENT_CLASS
+ #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)        \
        struct ftrace_data_offsets_##call {                             \
                tstruct;                                                \
        };
  
+ #undef DEFINE_EVENT
+ #define DEFINE_EVENT(template, name, proto, args)
+ #undef DEFINE_EVENT_PRINT
+ #define DEFINE_EVENT_PRINT(template, name, proto, args, print)        \
+       DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
  #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
  
  /*
  #undef __field
  #define __field(type, item)                                   \
        ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"      \
-                              "offset:%u;\tsize:%u;\n",                \
+                              "offset:%u;\tsize:%u;\tsigned:%u;\n",    \
                               (unsigned int)offsetof(typeof(field), item), \
-                              (unsigned int)sizeof(field.item));       \
+                              (unsigned int)sizeof(field.item),        \
+                              (unsigned int)is_signed_type(type));     \
        if (!ret)                                                       \
                return 0;
  
  #undef __array
  #define __array(type, item, len)                                              \
        ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t"    \
-                              "offset:%u;\tsize:%u;\n",                \
+                              "offset:%u;\tsize:%u;\tsigned:%u;\n",    \
                               (unsigned int)offsetof(typeof(field), item), \
-                              (unsigned int)sizeof(field.item));       \
+                              (unsigned int)sizeof(field.item),        \
+                              (unsigned int)is_signed_type(type));     \
        if (!ret)                                                       \
                return 0;
  
  #undef __dynamic_array
  #define __dynamic_array(type, item, len)                                     \
        ret = trace_seq_printf(s, "\tfield:__data_loc " #type "[] " #item ";\t"\
-                              "offset:%u;\tsize:%u;\n",                       \
+                              "offset:%u;\tsize:%u;\tsigned:%u;\n",           \
                               (unsigned int)offsetof(typeof(field),           \
                                        __data_loc_##item),                    \
-                              (unsigned int)sizeof(field.__data_loc_##item)); \
+                              (unsigned int)sizeof(field.__data_loc_##item), \
+                              (unsigned int)is_signed_type(type));     \
        if (!ret)                                                              \
                return 0;
  
  #undef __get_str
  
  #undef TP_printk
 -#define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args)
 +#define TP_printk(fmt, args...) "\"%s\", %s\n", fmt, __stringify(args)
  
  #undef TP_fast_assign
  #define TP_fast_assign(args...) args
  #undef TP_perf_assign
  #define TP_perf_assign(args...)
  
- #undef TRACE_EVENT
- #define TRACE_EVENT(call, proto, args, tstruct, func, print)          \
+ #undef DECLARE_EVENT_CLASS
+ #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print)  \
  static int                                                            \
- ftrace_format_##call(struct ftrace_event_call *unused,                        \
-                     struct trace_seq *s)                              \
+ ftrace_format_setup_##call(struct ftrace_event_call *unused,          \
+                          struct trace_seq *s)                         \
  {                                                                     \
        struct ftrace_raw_##call field __attribute__((unused));         \
        int ret = 0;                                                    \
                                                                        \
        tstruct;                                                        \
                                                                        \
+       return ret;                                                     \
+ }                                                                     \
+                                                                       \
+ static int                                                            \
+ ftrace_format_##call(struct ftrace_event_call *unused,                        \
+                    struct trace_seq *s)                               \
+ {                                                                     \
+       int ret = 0;                                                    \
+                                                                       \
+       ret = ftrace_format_setup_##call(unused, s);                    \
+       if (!ret)                                                       \
+               return ret;                                             \
+                                                                       \
+       ret = trace_seq_printf(s, "\nprint fmt: " print);               \
+                                                                       \
+       return ret;                                                     \
+ }
+ #undef DEFINE_EVENT
+ #define DEFINE_EVENT(template, name, proto, args)
+ #undef DEFINE_EVENT_PRINT
+ #define DEFINE_EVENT_PRINT(template, name, proto, args, print)                \
+ static int                                                            \
+ ftrace_format_##name(struct ftrace_event_call *unused,                        \
+                     struct trace_seq *s)                              \
+ {                                                                     \
+       int ret = 0;                                                    \
+                                                                       \
+       ret = ftrace_format_setup_##template(unused, s);                \
+       if (!ret)                                                       \
+               return ret;                                             \
+                                                                       \
        trace_seq_printf(s, "\nprint fmt: " print);                     \
                                                                        \
        return ret;                                                     \
                ftrace_print_symbols_seq(p, value, symbols);            \
        })
  
- #undef TRACE_EVENT
- #define TRACE_EVENT(call, proto, args, tstruct, assign, print)                \
+ #undef DECLARE_EVENT_CLASS
+ #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)        \
  static enum print_line_t                                              \
- ftrace_raw_output_##call(struct trace_iterator *iter, int flags)      \
+ ftrace_raw_output_id_##call(int event_id, const char *name,           \
+                           struct trace_iterator *iter, int flags)     \
  {                                                                     \
        struct trace_seq *s = &iter->seq;                               \
        struct ftrace_raw_##call *field;                                \
        struct trace_entry *entry;                                      \
        struct trace_seq *p;                                            \
+       int ret;                                                        \
+                                                                       \
+       entry = iter->ent;                                              \
+                                                                       \
+       if (entry->type != event_id) {                                  \
+               WARN_ON_ONCE(1);                                        \
+               return TRACE_TYPE_UNHANDLED;                            \
+       }                                                               \
+                                                                       \
+       field = (typeof(field))entry;                                   \
+                                                                       \
+       p = &get_cpu_var(ftrace_event_seq);                             \
+       trace_seq_init(p);                                              \
+       ret = trace_seq_printf(s, "%s: ", name);                        \
+       if (ret)                                                        \
+               ret = trace_seq_printf(s, print);                       \
+       put_cpu();                                                      \
+       if (!ret)                                                       \
+               return TRACE_TYPE_PARTIAL_LINE;                         \
+                                                                       \
+       return TRACE_TYPE_HANDLED;                                      \
+ }
+ #undef DEFINE_EVENT
+ #define DEFINE_EVENT(template, name, proto, args)                     \
+ static enum print_line_t                                              \
+ ftrace_raw_output_##name(struct trace_iterator *iter, int flags)      \
+ {                                                                     \
+       return ftrace_raw_output_id_##template(event_##name.id,         \
+                                              #name, iter, flags);     \
+ }
+ #undef DEFINE_EVENT_PRINT
+ #define DEFINE_EVENT_PRINT(template, call, proto, args, print)                \
+ static enum print_line_t                                              \
+ ftrace_raw_output_##call(struct trace_iterator *iter, int flags)      \
+ {                                                                     \
+       struct trace_seq *s = &iter->seq;                               \
+       struct ftrace_raw_##template *field;                            \
+       struct trace_entry *entry;                                      \
+       struct trace_seq *p;                                            \
        int ret;                                                        \
                                                                        \
        entry = iter->ent;                                              \
                                                                        \
        p = &get_cpu_var(ftrace_event_seq);                             \
        trace_seq_init(p);                                              \
-       ret = trace_seq_printf(s, #call ": " print);                    \
+       ret = trace_seq_printf(s, "%s: ", #call);                       \
+       if (ret)                                                        \
+               ret = trace_seq_printf(s, print);                       \
        put_cpu();                                                      \
        if (!ret)                                                       \
                return TRACE_TYPE_PARTIAL_LINE;                         \
                                                                        \
        return TRACE_TYPE_HANDLED;                                      \
  }
-       
  #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
  
  #undef __field_ext
  #undef __string
  #define __string(item, src) __dynamic_array(char, item, -1)
  
- #undef TRACE_EVENT
- #define TRACE_EVENT(call, proto, args, tstruct, func, print)          \
+ #undef DECLARE_EVENT_CLASS
+ #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print)  \
  static int                                                            \
  ftrace_define_fields_##call(struct ftrace_event_call *event_call)     \
  {                                                                     \
        return ret;                                                     \
  }
  
+ #undef DEFINE_EVENT
+ #define DEFINE_EVENT(template, name, proto, args)
+ #undef DEFINE_EVENT_PRINT
+ #define DEFINE_EVENT_PRINT(template, name, proto, args, print)        \
+       DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
  #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
  
  /*
        __data_size += (len) * sizeof(type);
  
  #undef __string
- #define __string(item, src) __dynamic_array(char, item, strlen(src) + 1)       \
+ #define __string(item, src) __dynamic_array(char, item, strlen(src) + 1)
  
- #undef TRACE_EVENT
- #define TRACE_EVENT(call, proto, args, tstruct, assign, print)                \
+ #undef DECLARE_EVENT_CLASS
+ #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)        \
  static inline int ftrace_get_offsets_##call(                          \
        struct ftrace_data_offsets_##call *__data_offsets, proto)       \
  {                                                                     \
        return __data_size;                                             \
  }
  
+ #undef DEFINE_EVENT
+ #define DEFINE_EVENT(template, name, proto, args)
+ #undef DEFINE_EVENT_PRINT
+ #define DEFINE_EVENT_PRINT(template, name, proto, args, print)        \
+       DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
  #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
  
  #ifdef CONFIG_EVENT_PROFILE
   *
   */
  
- #undef TRACE_EVENT
- #define TRACE_EVENT(call, proto, args, tstruct, assign, print)                \
+ #undef DECLARE_EVENT_CLASS
+ #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)
+ #undef DEFINE_EVENT
+ #define DEFINE_EVENT(template, name, proto, args)                     \
                                                                        \
- static void ftrace_profile_##call(proto);                             \
+ static void ftrace_profile_##name(proto);                             \
                                                                        \
- static int ftrace_profile_enable_##call(void)                         \
+ static int ftrace_profile_enable_##name(struct ftrace_event_call *unused)\
  {                                                                     \
-       return register_trace_##call(ftrace_profile_##call);            \
+       return register_trace_##name(ftrace_profile_##name);            \
  }                                                                     \
                                                                        \
- static void ftrace_profile_disable_##call(void)                               \
+ static void ftrace_profile_disable_##name(struct ftrace_event_call *unused)\
  {                                                                     \
-       unregister_trace_##call(ftrace_profile_##call);                 \
+       unregister_trace_##name(ftrace_profile_##name);                 \
  }
  
+ #undef DEFINE_EVENT_PRINT
+ #define DEFINE_EVENT_PRINT(template, name, proto, args, print)        \
+       DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
  #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
  
  #endif
   *    event_trace_printk(_RET_IP_, "<call>: " <fmt>);
   * }
   *
-  * static int ftrace_reg_event_<call>(void)
+  * static int ftrace_reg_event_<call>(struct ftrace_event_call *unused)
   * {
   *    int ret;
   *
   *    return ret;
   * }
   *
-  * static void ftrace_unreg_event_<call>(void)
+  * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused)
   * {
   *    unregister_trace_<call>(ftrace_event_<call>);
   * }
   *    trace_current_buffer_unlock_commit(buffer, event, irq_flags, pc);
   * }
   *
-  * static int ftrace_raw_reg_event_<call>(void)
+  * static int ftrace_raw_reg_event_<call>(struct ftrace_event_call *unused)
   * {
   *    int ret;
   *
   *    return ret;
   * }
   *
-  * static void ftrace_unreg_event_<call>(void)
+  * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused)
   * {
   *    unregister_trace_<call>(ftrace_raw_event_<call>);
   * }
   *    .trace                  = ftrace_raw_output_<call>, <-- stage 2
   * };
   *
-  * static int ftrace_raw_init_event_<call>(void)
+  * static int ftrace_raw_init_event_<call>(struct ftrace_event_call *unused)
   * {
   *    int id;
   *
  #define __assign_str(dst, src)                                                \
        strcpy(__get_str(dst), src);
  
- #undef TRACE_EVENT
- #define TRACE_EVENT(call, proto, args, tstruct, assign, print)                \
+ #undef DECLARE_EVENT_CLASS
+ #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)        \
                                                                        \
- static struct ftrace_event_call event_##call;                         \
-                                                                       \
- static void ftrace_raw_event_##call(proto)                            \
+ static void ftrace_raw_event_id_##call(struct ftrace_event_call *event_call, \
+                                      proto)                           \
  {                                                                     \
        struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
-       struct ftrace_event_call *event_call = &event_##call;           \
        struct ring_buffer_event *event;                                \
        struct ftrace_raw_##call *entry;                                \
        struct ring_buffer *buffer;                                     \
        __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \
                                                                        \
        event = trace_current_buffer_lock_reserve(&buffer,              \
-                                event_##call.id,                       \
+                                event_call->id,                        \
                                 sizeof(*entry) + __data_size,          \
                                 irq_flags, pc);                        \
        if (!event)                                                     \
        if (!filter_current_check_discard(buffer, event_call, entry, event)) \
                trace_nowake_buffer_unlock_commit(buffer,               \
                                                  event, irq_flags, pc); \
+ }
+ #undef DEFINE_EVENT
+ #define DEFINE_EVENT(template, call, proto, args)                     \
+                                                                       \
+ static void ftrace_raw_event_##call(proto)                            \
+ {                                                                     \
+       ftrace_raw_event_id_##template(&event_##call, args);            \
  }                                                                     \
                                                                        \
- static int ftrace_raw_reg_event_##call(void *ptr)                     \
+ static int ftrace_raw_reg_event_##call(struct ftrace_event_call *unused)\
  {                                                                     \
        int ret;                                                        \
                                                                        \
        return ret;                                                     \
  }                                                                     \
                                                                        \
- static void ftrace_raw_unreg_event_##call(void *ptr)                  \
+ static void ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused)\
  {                                                                     \
        unregister_trace_##call(ftrace_raw_event_##call);               \
  }                                                                     \
@@@ -606,7 -746,7 +746,7 @@@ static struct trace_event ftrace_event_
        .trace                  = ftrace_raw_output_##call,             \
  };                                                                    \
                                                                        \
- static int ftrace_raw_init_event_##call(void)                         \
+ static int ftrace_raw_init_event_##call(struct ftrace_event_call *unused)\
  {                                                                     \
        int id;                                                         \
                                                                        \
        event_##call.id = id;                                           \
        INIT_LIST_HEAD(&event_##call.fields);                           \
        return 0;                                                       \
- }                                                                     \
+ }
+ #undef DEFINE_EVENT_PRINT
+ #define DEFINE_EVENT_PRINT(template, name, proto, args, print)        \
+       DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
+ #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+ #undef DECLARE_EVENT_CLASS
+ #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)
+ #undef DEFINE_EVENT
+ #define DEFINE_EVENT(template, call, proto, args)                     \
+                                                                       \
+ static struct ftrace_event_call __used                                        \
+ __attribute__((__aligned__(4)))                                               \
+ __attribute__((section("_ftrace_events"))) event_##call = {           \
+       .name                   = #call,                                \
+       .system                 = __stringify(TRACE_SYSTEM),            \
+       .event                  = &ftrace_event_type_##call,            \
+       .raw_init               = ftrace_raw_init_event_##call,         \
+       .regfunc                = ftrace_raw_reg_event_##call,          \
+       .unregfunc              = ftrace_raw_unreg_event_##call,        \
+       .show_format            = ftrace_format_##template,             \
+       .define_fields          = ftrace_define_fields_##template,      \
+       _TRACE_PROFILE_INIT(call)                                       \
+ }
+ #undef DEFINE_EVENT_PRINT
+ #define DEFINE_EVENT_PRINT(template, call, proto, args, print)                \
                                                                        \
  static struct ftrace_event_call __used                                        \
  __attribute__((__aligned__(4)))                                               \
@@@ -628,7 -797,7 +797,7 @@@ __attribute__((section("_ftrace_events"
        .regfunc                = ftrace_raw_reg_event_##call,          \
        .unregfunc              = ftrace_raw_unreg_event_##call,        \
        .show_format            = ftrace_format_##call,                 \
-       .define_fields          = ftrace_define_fields_##call,          \
+       .define_fields          = ftrace_define_fields_##template,      \
        _TRACE_PROFILE_INIT(call)                                       \
  }
  
   *    struct ftrace_event_call *event_call = &event_<call>;
   *    extern void perf_tp_event(int, u64, u64, void *, int);
   *    struct ftrace_raw_##call *entry;
+  *    struct perf_trace_buf *trace_buf;
   *    u64 __addr = 0, __count = 1;
   *    unsigned long irq_flags;
   *    struct trace_entry *ent;
   *    __cpu = smp_processor_id();
   *
   *    if (in_nmi())
-  *            raw_data = rcu_dereference(trace_profile_buf_nmi);
+  *            trace_buf = rcu_dereference(perf_trace_buf_nmi);
   *    else
-  *            raw_data = rcu_dereference(trace_profile_buf);
+  *            trace_buf = rcu_dereference(perf_trace_buf);
   *
-  *    if (!raw_data)
+  *    if (!trace_buf)
   *            goto end;
   *
-  *    raw_data = per_cpu_ptr(raw_data, __cpu);
+  *    trace_buf = per_cpu_ptr(trace_buf, __cpu);
+  *
+  *    // Avoid recursion from perf that could mess up the buffer
+  *    if (trace_buf->recursion++)
+  *            goto end_recursion;
+  *
+  *    raw_data = trace_buf->buf;
+  *
+  *    // Make recursion update visible before entering perf_tp_event
+  *    // so that we protect from perf recursions.
+  *
+  *    barrier();
   *
   *    //zero dead bytes from alignment to avoid stack leak to userspace:
   *    *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL;
  #undef __perf_count
  #define __perf_count(c) __count = (c)
  
- #undef TRACE_EVENT
- #define TRACE_EVENT(call, proto, args, tstruct, assign, print)                \
- static void ftrace_profile_##call(proto)                              \
+ #undef DECLARE_EVENT_CLASS
+ #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)        \
+ static void                                                           \
+ ftrace_profile_templ_##call(struct ftrace_event_call *event_call,     \
+                           proto)                                      \
  {                                                                     \
        struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
-       struct ftrace_event_call *event_call = &event_##call;           \
-       extern void perf_tp_event(int, u64, u64, void *, int);  \
+       extern int perf_swevent_get_recursion_context(void);            \
+       extern void perf_swevent_put_recursion_context(int rctx);       \
+       extern void perf_tp_event(int, u64, u64, void *, int);          \
        struct ftrace_raw_##call *entry;                                \
        u64 __addr = 0, __count = 1;                                    \
        unsigned long irq_flags;                                        \
        struct trace_entry *ent;                                        \
        int __entry_size;                                               \
        int __data_size;                                                \
+       char *trace_buf;                                                \
        char *raw_data;                                                 \
        int __cpu;                                                      \
+       int rctx;                                                       \
        int pc;                                                         \
                                                                        \
        pc = preempt_count();                                           \
                return;                                                 \
                                                                        \
        local_irq_save(irq_flags);                                      \
+                                                                       \
+       rctx = perf_swevent_get_recursion_context();                    \
+       if (rctx < 0)                                                   \
+               goto end_recursion;                                     \
+                                                                       \
        __cpu = smp_processor_id();                                     \
                                                                        \
        if (in_nmi())                                                   \
-               raw_data = rcu_dereference(trace_profile_buf_nmi);              \
+               trace_buf = rcu_dereference(perf_trace_buf_nmi);        \
        else                                                            \
-               raw_data = rcu_dereference(trace_profile_buf);          \
+               trace_buf = rcu_dereference(perf_trace_buf);            \
                                                                        \
-       if (!raw_data)                                                  \
+       if (!trace_buf)                                                 \
                goto end;                                               \
                                                                        \
-       raw_data = per_cpu_ptr(raw_data, __cpu);                        \
+       raw_data = per_cpu_ptr(trace_buf, __cpu);                       \
                                                                        \
        *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL;         \
        entry = (struct ftrace_raw_##call *)raw_data;                   \
                             __entry_size);                             \
                                                                        \
  end:                                                                  \
+       perf_swevent_put_recursion_context(rctx);                       \
+ end_recursion:                                                                \
        local_irq_restore(irq_flags);                                   \
                                                                        \
  }
  
+ #undef DEFINE_EVENT
+ #define DEFINE_EVENT(template, call, proto, args)             \
+ static void ftrace_profile_##call(proto)                      \
+ {                                                             \
+       struct ftrace_event_call *event_call = &event_##call;   \
+                                                               \
+       ftrace_profile_templ_##template(event_call, args);      \
+ }
+ #undef DEFINE_EVENT_PRINT
+ #define DEFINE_EVENT_PRINT(template, name, proto, args, print)        \
+       DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
  #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
  #endif /* CONFIG_EVENT_PROFILE */
  
diff --combined kernel/Makefile
index dcf6789bf547e5af8e1c569b743ac72a2af4af93,6b7ce8173dfdc063676dd6d2a565fbcc56cc7603..982c50e2ce534df9a3bf5a704580fd0e13fe7f5b
@@@ -21,6 -21,7 +21,7 @@@ CFLAGS_REMOVE_mutex-debug.o = -p
  CFLAGS_REMOVE_rtmutex-debug.o = -pg
  CFLAGS_REMOVE_cgroup-debug.o = -pg
  CFLAGS_REMOVE_sched_clock.o = -pg
+ CFLAGS_REMOVE_perf_event.o = -pg
  endif
  
  obj-$(CONFIG_FREEZER) += freezer.o
@@@ -82,7 -83,6 +83,7 @@@ obj-$(CONFIG_RCU_TORTURE_TEST) += rcuto
  obj-$(CONFIG_TREE_RCU) += rcutree.o
  obj-$(CONFIG_TREE_PREEMPT_RCU) += rcutree.o
  obj-$(CONFIG_TREE_RCU_TRACE) += rcutree_trace.o
 +obj-$(CONFIG_TINY_RCU) += rcutiny.o
  obj-$(CONFIG_RELAY) += relay.o
  obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
  obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
@@@ -95,8 -95,8 +96,9 @@@ obj-$(CONFIG_X86_DS) += trace
  obj-$(CONFIG_RING_BUFFER) += trace/
  obj-$(CONFIG_SMP) += sched_cpupri.o
  obj-$(CONFIG_SLOW_WORK) += slow-work.o
 +obj-$(CONFIG_SLOW_WORK_DEBUG) += slow-work-debugfs.o
  obj-$(CONFIG_PERF_EVENTS) += perf_event.o
+ obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
  
  ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
  # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --combined kernel/kprobes.c
index 1494e85b35f29bb5c006c34221eadfedceee934d,84495958e703366eef86906d1e0ff4aa1cb2d2cd..e5342a344c43bee9140d9127f1fe907b21149e8d
@@@ -90,6 -90,9 +90,9 @@@ static spinlock_t *kretprobe_table_lock
   */
  static struct kprobe_blackpoint kprobe_blacklist[] = {
        {"preempt_schedule",},
+       {"native_get_debugreg",},
+       {"irq_entries_start",},
+       {"common_interrupt",},
        {NULL}    /* Terminator */
  };
  
@@@ -673,6 -676,40 +676,40 @@@ static kprobe_opcode_t __kprobes *kprob
        return (kprobe_opcode_t *)(((char *)addr) + p->offset);
  }
  
+ /* Check passed kprobe is valid and return kprobe in kprobe_table. */
+ static struct kprobe * __kprobes __get_valid_kprobe(struct kprobe *p)
+ {
+       struct kprobe *old_p, *list_p;
+       old_p = get_kprobe(p->addr);
+       if (unlikely(!old_p))
+               return NULL;
+       if (p != old_p) {
+               list_for_each_entry_rcu(list_p, &old_p->list, list)
+                       if (list_p == p)
+                       /* kprobe p is a valid probe */
+                               goto valid;
+               return NULL;
+       }
+ valid:
+       return old_p;
+ }
+ /* Return error if the kprobe is being re-registered */
+ static inline int check_kprobe_rereg(struct kprobe *p)
+ {
+       int ret = 0;
+       struct kprobe *old_p;
+       mutex_lock(&kprobe_mutex);
+       old_p = __get_valid_kprobe(p);
+       if (old_p)
+               ret = -EINVAL;
+       mutex_unlock(&kprobe_mutex);
+       return ret;
+ }
  int __kprobes register_kprobe(struct kprobe *p)
  {
        int ret = 0;
                return -EINVAL;
        p->addr = addr;
  
+       ret = check_kprobe_rereg(p);
+       if (ret)
+               return ret;
        preempt_disable();
        if (!kernel_text_address((unsigned long) p->addr) ||
            in_kprobes_functions((unsigned long) p->addr)) {
@@@ -754,26 -795,6 +795,6 @@@ out
  }
  EXPORT_SYMBOL_GPL(register_kprobe);
  
- /* Check passed kprobe is valid and return kprobe in kprobe_table. */
- static struct kprobe * __kprobes __get_valid_kprobe(struct kprobe *p)
- {
-       struct kprobe *old_p, *list_p;
-       old_p = get_kprobe(p->addr);
-       if (unlikely(!old_p))
-               return NULL;
-       if (p != old_p) {
-               list_for_each_entry_rcu(list_p, &old_p->list, list)
-                       if (list_p == p)
-                       /* kprobe p is a valid probe */
-                               goto valid;
-               return NULL;
-       }
- valid:
-       return old_p;
- }
  /*
   * Unregister a kprobe without a scheduler synchronization.
   */
@@@ -1014,9 -1035,9 +1035,9 @@@ int __kprobes register_kretprobe(struc
        /* Pre-allocate memory for max kretprobe instances */
        if (rp->maxactive <= 0) {
  #ifdef CONFIG_PREEMPT
 -              rp->maxactive = max(10, 2 * NR_CPUS);
 +              rp->maxactive = max(10, 2 * num_possible_cpus());
  #else
 -              rp->maxactive = NR_CPUS;
 +              rp->maxactive = num_possible_cpus();
  #endif
        }
        spin_lock_init(&rp->lock);
@@@ -1141,6 -1162,13 +1162,13 @@@ static void __kprobes kill_kprobe(struc
        arch_remove_kprobe(p);
  }
  
+ void __kprobes dump_kprobe(struct kprobe *kp)
+ {
+       printk(KERN_WARNING "Dumping kprobe:\n");
+       printk(KERN_WARNING "Name: %s\nAddress: %p\nOffset: %x\n",
+              kp->symbol_name, kp->addr, kp->offset);
+ }
  /* Module notifier call back, checking kprobes on the module */
  static int __kprobes kprobes_module_callback(struct notifier_block *nb,
                                             unsigned long val, void *data)
diff --combined kernel/signal.c
index fe08008133dad06e0acd6efdc98db25c64367565,93e72e5feae63bc0e9b6bb9e6da3ba3d57b8fcb4..6b982f2cf524d82e6b72f276f7d9010df9007e47
  #include <linux/ptrace.h>
  #include <linux/signal.h>
  #include <linux/signalfd.h>
 +#include <linux/ratelimit.h>
  #include <linux/tracehook.h>
  #include <linux/capability.h>
  #include <linux/freezer.h>
  #include <linux/pid_namespace.h>
  #include <linux/nsproxy.h>
- #include <trace/events/sched.h>
+ #define CREATE_TRACE_POINTS
+ #include <trace/events/signal.h>
  
  #include <asm/param.h>
  #include <asm/uaccess.h>
@@@ -42,8 -42,6 +43,8 @@@
  
  static struct kmem_cache *sigqueue_cachep;
  
 +int print_fatal_signals __read_mostly;
 +
  static void __user *sig_handler(struct task_struct *t, int sig)
  {
        return t->sighand->action[sig - 1].sa.sa_handler;
@@@ -162,7 -160,7 +163,7 @@@ int next_signal(struct sigpending *pend
  {
        unsigned long i, *s, *m, x;
        int sig = 0;
 -      
 +
        s = pending->signal.sig;
        m = mask->sig;
        switch (_NSIG_WORDS) {
                        sig = ffz(~x) + 1;
                break;
        }
 -      
 +
        return sig;
  }
  
 +static inline void print_dropped_signal(int sig)
 +{
 +      static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10);
 +
 +      if (!print_fatal_signals)
 +              return;
 +
 +      if (!__ratelimit(&ratelimit_state))
 +              return;
 +
 +      printk(KERN_INFO "%s/%d: reached RLIMIT_SIGPENDING, dropped signal %d\n",
 +                              current->comm, current->pid, sig);
 +}
 +
  /*
   * allocate a new signal queue record
   * - this may be called without locks if and only if t == current, otherwise an
   *   appopriate lock must be held to stop the target task from exiting
   */
 -static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
 -                                       int override_rlimit)
 +static struct sigqueue *
 +__sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimit)
  {
        struct sigqueue *q = NULL;
        struct user_struct *user;
         */
        user = get_uid(__task_cred(t)->user);
        atomic_inc(&user->sigpending);
 +
        if (override_rlimit ||
            atomic_read(&user->sigpending) <=
 -                      t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
 +                      t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur) {
                q = kmem_cache_alloc(sigqueue_cachep, flags);
 +      } else {
 +              print_dropped_signal(sig);
 +      }
 +
        if (unlikely(q == NULL)) {
                atomic_dec(&user->sigpending);
                free_uid(user);
@@@ -856,7 -835,7 +857,7 @@@ static int __send_signal(int sig, struc
        struct sigqueue *q;
        int override_rlimit;
  
-       trace_sched_signal_send(sig, t);
+       trace_signal_generate(sig, info, t);
  
        assert_spin_locked(&t->sighand->siglock);
  
        else
                override_rlimit = 0;
  
 -      q = __sigqueue_alloc(t, GFP_ATOMIC | __GFP_NOTRACK_FALSE_POSITIVE,
 +      q = __sigqueue_alloc(sig, t, GFP_ATOMIC | __GFP_NOTRACK_FALSE_POSITIVE,
                override_rlimit);
        if (q) {
                list_add_tail(&q->list, &pending->list);
                        break;
                }
        } else if (!is_si_special(info)) {
-               if (sig >= SIGRTMIN && info->si_code != SI_USER)
-               /*
-                * Queue overflow, abort.  We may abort if the signal was rt
-                * and sent by user using something other than kill().
-                */
+               if (sig >= SIGRTMIN && info->si_code != SI_USER) {
+                       /*
+                        * Queue overflow, abort.  We may abort if the
+                        * signal was rt and sent by user using something
+                        * other than kill().
+                        */
+                       trace_signal_overflow_fail(sig, group, info);
                        return -EAGAIN;
+               } else {
+                       /*
+                        * This is a silent loss of information.  We still
+                        * send the signal, but the *info bits are lost.
+                        */
+                       trace_signal_lose_info(sig, group, info);
+               }
        }
  
  out_set:
@@@ -947,6 -935,8 +957,6 @@@ static int send_signal(int sig, struct 
        return __send_signal(sig, info, t, group, from_ancestor_ns);
  }
  
 -int print_fatal_signals;
 -
  static void print_fatal_signal(struct pt_regs *regs, int signr)
  {
        printk("%s/%d: potentially unexpected fatal signal %d.\n",
@@@ -1313,19 -1303,19 +1323,19 @@@ EXPORT_SYMBOL(kill_pid)
   * These functions support sending signals using preallocated sigqueue
   * structures.  This is needed "because realtime applications cannot
   * afford to lose notifications of asynchronous events, like timer
 - * expirations or I/O completions".  In the case of Posix Timers 
 + * expirations or I/O completions".  In the case of Posix Timers
   * we allocate the sigqueue structure from the timer_create.  If this
   * allocation fails we are able to report the failure to the application
   * with an EAGAIN error.
   */
 - 
  struct sigqueue *sigqueue_alloc(void)
  {
 -      struct sigqueue *q;
 +      struct sigqueue *q = __sigqueue_alloc(-1, current, GFP_KERNEL, 0);
  
 -      if ((q = __sigqueue_alloc(current, GFP_KERNEL, 0)))
 +      if (q)
                q->flags |= SIGQUEUE_PREALLOC;
 -      return(q);
 +
 +      return q;
  }
  
  void sigqueue_free(struct sigqueue *q)
@@@ -1859,6 -1849,9 +1869,9 @@@ relock
                        ka = &sighand->action[signr-1];
                }
  
+               /* Trace actually delivered signals. */
+               trace_signal_deliver(signr, info, ka);
                if (ka->sa.sa_handler == SIG_IGN) /* Do nothing.  */
                        continue;
                if (ka->sa.sa_handler != SIG_DFL) {
index a72c6e03deecb5224c568ba61f2e123a87bec1a8,db223fe8887fcac365391af9bbb98cb31ca41b01..a1ca4956ab5ec3673b04ddd839dd9edec26d1bf4
@@@ -397,18 -397,21 +397,21 @@@ int ring_buffer_print_page_header(struc
        int ret;
  
        ret = trace_seq_printf(s, "\tfield: u64 timestamp;\t"
-                              "offset:0;\tsize:%u;\n",
-                              (unsigned int)sizeof(field.time_stamp));
+                              "offset:0;\tsize:%u;\tsigned:%u;\n",
+                              (unsigned int)sizeof(field.time_stamp),
+                              (unsigned int)is_signed_type(u64));
  
        ret = trace_seq_printf(s, "\tfield: local_t commit;\t"
-                              "offset:%u;\tsize:%u;\n",
+                              "offset:%u;\tsize:%u;\tsigned:%u;\n",
                               (unsigned int)offsetof(typeof(field), commit),
-                              (unsigned int)sizeof(field.commit));
+                              (unsigned int)sizeof(field.commit),
+                              (unsigned int)is_signed_type(long));
  
        ret = trace_seq_printf(s, "\tfield: char data;\t"
-                              "offset:%u;\tsize:%u;\n",
+                              "offset:%u;\tsize:%u;\tsigned:%u;\n",
                               (unsigned int)offsetof(typeof(field), data),
-                              (unsigned int)BUF_PAGE_SIZE);
+                              (unsigned int)BUF_PAGE_SIZE,
+                              (unsigned int)is_signed_type(char));
  
        return ret;
  }
@@@ -1787,9 -1790,9 +1790,9 @@@ rb_reset_tail(struct ring_buffer_per_cp
  static struct ring_buffer_event *
  rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer,
             unsigned long length, unsigned long tail,
 -           struct buffer_page *commit_page,
             struct buffer_page *tail_page, u64 *ts)
  {
 +      struct buffer_page *commit_page = cpu_buffer->commit_page;
        struct ring_buffer *buffer = cpu_buffer->buffer;
        struct buffer_page *next_page;
        int ret;
@@@ -1892,10 -1895,13 +1895,10 @@@ static struct ring_buffer_event 
  __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
                  unsigned type, unsigned long length, u64 *ts)
  {
 -      struct buffer_page *tail_page, *commit_page;
 +      struct buffer_page *tail_page;
        struct ring_buffer_event *event;
        unsigned long tail, write;
  
 -      commit_page = cpu_buffer->commit_page;
 -      /* we just need to protect against interrupts */
 -      barrier();
        tail_page = cpu_buffer->tail_page;
        write = local_add_return(length, &tail_page->write);
  
        /* See if we shot pass the end of this buffer page */
        if (write > BUF_PAGE_SIZE)
                return rb_move_tail(cpu_buffer, length, tail,
 -                                  commit_page, tail_page, ts);
 +                                  tail_page, ts);
  
        /* We reserved something on the buffer */
  
index c74848ddb85a236916bfb7bdf64d322a6f37008d,934d81fb4ca46b2c8b654d8b7ac234b87f9ab481..dff8c84ddf17589543ca90e71af630cf7b0755b7
  struct ____ftrace_##name {                                    \
        tstruct                                                 \
  };                                                            \
 -static void __used ____ftrace_check_##name(void)              \
 +static void __always_unused ____ftrace_check_##name(void)     \
  {                                                             \
        struct ____ftrace_##name *__entry = NULL;               \
                                                                \
 -      /* force cmpile-time check on F_printk() */             \
 +      /* force compile-time check on F_printk() */            \
        printk(print);                                          \
  }
  
  #undef __field
  #define __field(type, item)                                           \
        ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"      \
-                              "offset:%zu;\tsize:%zu;\n",              \
+                              "offset:%zu;\tsize:%zu;\tsigned:%u;\n",  \
                               offsetof(typeof(field), item),           \
-                              sizeof(field.item));                     \
+                              sizeof(field.item), is_signed_type(type)); \
        if (!ret)                                                       \
                return 0;
  
  #undef __field_desc
  #define __field_desc(type, container, item)                           \
        ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"      \
-                              "offset:%zu;\tsize:%zu;\n",              \
+                              "offset:%zu;\tsize:%zu;\tsigned:%u;\n",  \
                               offsetof(typeof(field), container.item), \
-                              sizeof(field.container.item));           \
+                              sizeof(field.container.item),            \
+                              is_signed_type(type));                   \
        if (!ret)                                                       \
                return 0;
  
  #undef __array
  #define __array(type, item, len)                                      \
        ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
-                              "offset:%zu;\tsize:%zu;\n",              \
-                              offsetof(typeof(field), item),   \
-                              sizeof(field.item));             \
+                              "offset:%zu;\tsize:%zu;\tsigned:%u;\n",  \
+                              offsetof(typeof(field), item),           \
+                              sizeof(field.item), is_signed_type(type)); \
        if (!ret)                                                       \
                return 0;
  
  #undef __array_desc
  #define __array_desc(type, container, item, len)                      \
        ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
-                              "offset:%zu;\tsize:%zu;\n",              \
+                              "offset:%zu;\tsize:%zu;\tsigned:%u;\n",  \
                               offsetof(typeof(field), container.item), \
-                              sizeof(field.container.item));           \
+                              sizeof(field.container.item),            \
+                              is_signed_type(type));                   \
        if (!ret)                                                       \
                return 0;
  
  #undef __dynamic_array
  #define __dynamic_array(type, item)                                   \
        ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"      \
-                              "offset:%zu;\tsize:0;\n",                \
-                              offsetof(typeof(field), item));          \
+                              "offset:%zu;\tsize:0;\tsigned:%u;\n",    \
+                              offsetof(typeof(field), item),           \
+                              is_signed_type(type));                   \
        if (!ret)                                                       \
                return 0;
  
@@@ -131,7 -134,6 +134,6 @@@ ftrace_format_##name(struct ftrace_even
  
  #include "trace_entries.h"
  
  #undef __field
  #define __field(type, item)                                           \
        ret = trace_define_field(event_call, #type, #item,              \
@@@ -193,6 -195,11 +195,11 @@@ ftrace_define_fields_##name(struct ftra
  
  #include "trace_entries.h"
  
+ static int ftrace_raw_init_event(struct ftrace_event_call *call)
+ {
+       INIT_LIST_HEAD(&call->fields);
+       return 0;
+ }
  
  #undef __field
  #define __field(type, item)
  
  #undef FTRACE_ENTRY
  #define FTRACE_ENTRY(call, struct_name, type, tstruct, print)         \
- static int ftrace_raw_init_event_##call(void);                                \
                                                                        \
  struct ftrace_event_call __used                                               \
  __attribute__((__aligned__(4)))                                               \
@@@ -219,14 -225,9 +225,9 @@@ __attribute__((section("_ftrace_events"
        .name                   = #call,                                \
        .id                     = type,                                 \
        .system                 = __stringify(TRACE_SYSTEM),            \
-       .raw_init               = ftrace_raw_init_event_##call,         \
+       .raw_init               = ftrace_raw_init_event,                \
        .show_format            = ftrace_format_##call,                 \
        .define_fields          = ftrace_define_fields_##call,          \
  };                                                                    \
- static int ftrace_raw_init_event_##call(void)                         \
- {                                                                     \
-       INIT_LIST_HEAD(&event_##call.fields);                           \
-       return 0;                                                       \
- }                                                                     \
  
  #include "trace_entries.h"