Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 30 Apr 2013 14:41:01 +0000 (07:41 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 30 Apr 2013 14:41:01 +0000 (07:41 -0700)
Pull perf updates from Ingo Molnar:
 "Features:

   - Add "uretprobes" - an optimization to uprobes, like kretprobes are
     an optimization to kprobes.  "perf probe -x file sym%return" now
     works like kretprobes.  By Oleg Nesterov.

   - Introduce per core aggregation in 'perf stat', from Stephane
     Eranian.

   - Add memory profiling via PEBS, from Stephane Eranian.

   - Event group view for 'annotate' in --stdio, --tui and --gtk, from
     Namhyung Kim.

   - Add support for AMD NB and L2I "uncore" counters, by Jacob Shin.

   - Add Ivy Bridge-EP uncore support, by Zheng Yan

   - IBM zEnterprise EC12 oprofile support patchlet from Robert Richter.

   - Add perf test entries for checking breakpoint overflow signal
     handler issues, from Jiri Olsa.

   - Add perf test entry for for checking number of EXIT events, from
     Namhyung Kim.

   - Add perf test entries for checking --cpu in record and stat, from
     Jiri Olsa.

   - Introduce perf stat --repeat forever, from Frederik Deweerdt.

   - Add --no-demangle to report/top, from Namhyung Kim.

   - PowerPC fixes plus a couple of cleanups/optimizations in uprobes
     and trace_uprobes, by Oleg Nesterov.

  Various fixes and refactorings:

   - Fix dependency of the python binding wrt libtraceevent, from
     Naohiro Aota.

   - Simplify some perf_evlist methods and to allow 'stat' to share code
     with 'record' and 'trace', by Arnaldo Carvalho de Melo.

   - Remove dead code in related to libtraceevent integration, from
     Namhyung Kim.

   - Revert "perf sched: Handle PERF_RECORD_EXIT events" to get 'perf
     sched lat' back working, by Arnaldo Carvalho de Melo

   - We don't use Newt anymore, just plain libslang, by Arnaldo Carvalho
     de Melo.

   - Kill a bunch of die() calls, from Namhyung Kim.

   - Fix build on non-glibc systems due to libio.h absence, from Cody P
     Schafer.

   - Remove some perf_session and tracing dead code, from David Ahern.

   - Honor parallel jobs, fix from Borislav Petkov

   - Introduce tools/lib/lk library, initially just removing duplication
     among tools/perf and tools/vm.  from Borislav Petkov

  ... and many more I missed to list, see the shortlog and git log for
  more details."

* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (136 commits)
  perf/x86/intel/P4: Robistify P4 PMU types
  perf/x86/amd: Fix AMD NB and L2I "uncore" support
  perf/x86/amd: Remove old-style NB counter support from perf_event_amd.c
  perf/x86: Check all MSRs before passing hw check
  perf/x86/amd: Add support for AMD NB and L2I "uncore" counters
  perf/x86/intel: Add Ivy Bridge-EP uncore support
  perf/x86/intel: Fix SNB-EP CBO and PCU uncore PMU filter management
  perf/x86: Avoid kfree() in CPU_{STARTING,DYING}
  uprobes/perf: Avoid perf_trace_buf_prepare/submit if ->perf_events is empty
  uprobes/tracing: Don't pass addr=ip to perf_trace_buf_submit()
  uprobes/tracing: Change create_trace_uprobe() to support uretprobes
  uprobes/tracing: Make seq_printf() code uretprobe-friendly
  uprobes/tracing: Make register_uprobe_event() paths uretprobe-friendly
  uprobes/tracing: Make uprobe_{trace,perf}_print() uretprobe-friendly
  uprobes/tracing: Introduce is_ret_probe() and uretprobe_dispatcher()
  uprobes/tracing: Introduce uprobe_{trace,perf}_print() helpers
  uprobes/tracing: Generalize struct uprobe_trace_entry_head
  uprobes/tracing: Kill the pointless local_save_flags/preempt_count calls
  uprobes/tracing: Kill the pointless seq_print_ip_sym() call
  uprobes/tracing: Kill the pointless task_pt_regs() calls
  ...

1  2 
Makefile
arch/x86/kernel/cpu/Makefile
kernel/events/core.c
kernel/trace/trace.h

diff --combined Makefile
+++ b/Makefile
@@@ -1,7 -1,7 +1,7 @@@
  VERSION = 3
  PATCHLEVEL = 9
  SUBLEVEL = 0
 -EXTRAVERSION = -rc7
 +EXTRAVERSION =
  NAME = Unicycling Gorilla
  
  # *DOCUMENTATION*
@@@ -513,8 -513,7 +513,8 @@@ ifeq ($(KBUILD_EXTMOD),
  # Carefully list dependencies so we do not try to build scripts twice
  # in parallel
  PHONY += scripts
 -scripts: scripts_basic include/config/auto.conf include/config/tristate.conf
 +scripts: scripts_basic include/config/auto.conf include/config/tristate.conf \
 +       asm-generic
        $(Q)$(MAKE) $(build)=$(@)
  
  # Objects we will link into vmlinux / subdirs we need to visit
@@@ -1332,11 -1331,11 +1332,11 @@@ kernelversion
  # Clear a bunch of variables before executing the submake
  tools/: FORCE
        $(Q)mkdir -p $(objtree)/tools
-       $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/
+       $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(objtree) subdir=tools -C $(src)/tools/
  
  tools/%: FORCE
        $(Q)mkdir -p $(objtree)/tools
-       $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/ $*
+       $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(objtree) subdir=tools -C $(src)/tools/ $*
  
  # Single targets
  # ---------------------------------------------------------------------------
@@@ -31,7 -31,7 +31,7 @@@ obj-$(CONFIG_CPU_SUP_UMC_32)          += umc.
  obj-$(CONFIG_PERF_EVENTS)             += perf_event.o
  
  ifdef CONFIG_PERF_EVENTS
- obj-$(CONFIG_CPU_SUP_AMD)             += perf_event_amd.o
+ obj-$(CONFIG_CPU_SUP_AMD)             += perf_event_amd.o perf_event_amd_uncore.o
  obj-$(CONFIG_CPU_SUP_INTEL)           += perf_event_p6.o perf_event_knc.o perf_event_p4.o
  obj-$(CONFIG_CPU_SUP_INTEL)           += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o
  obj-$(CONFIG_CPU_SUP_INTEL)           += perf_event_intel_uncore.o
@@@ -43,10 -43,10 +43,10 @@@ obj-$(CONFIG_MTRR)                 += mtrr
  obj-$(CONFIG_X86_LOCAL_APIC)          += perfctr-watchdog.o perf_event_amd_ibs.o
  
  quiet_cmd_mkcapflags = MKCAP   $@
 -      cmd_mkcapflags = $(PERL) $(srctree)/$(src)/mkcapflags.pl $< $@
 +      cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $< $@
  
  cpufeature = $(src)/../../include/asm/cpufeature.h
  
  targets += capflags.c
 -$(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.pl FORCE
 +$(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE
        $(call if_changed,mkcapflags)
diff --combined kernel/events/core.c
@@@ -37,6 -37,7 +37,7 @@@
  #include <linux/ftrace_event.h>
  #include <linux/hw_breakpoint.h>
  #include <linux/mm_types.h>
+ #include <linux/cgroup.h>
  
  #include "internal.h"
  
@@@ -234,6 -235,20 +235,20 @@@ static void perf_ctx_unlock(struct perf
  #ifdef CONFIG_CGROUP_PERF
  
  /*
+  * perf_cgroup_info keeps track of time_enabled for a cgroup.
+  * This is a per-cpu dynamically allocated data structure.
+  */
+ struct perf_cgroup_info {
+       u64                             time;
+       u64                             timestamp;
+ };
+ struct perf_cgroup {
+       struct cgroup_subsys_state      css;
+       struct perf_cgroup_info __percpu *info;
+ };
+ /*
   * Must ensure cgroup is pinned (css_get) before calling
   * this function. In other words, we cannot call this function
   * if there is no cgroup event for the current CPU context.
@@@ -251,22 -266,7 +266,22 @@@ perf_cgroup_match(struct perf_event *ev
        struct perf_event_context *ctx = event->ctx;
        struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);
  
 -      return !event->cgrp || event->cgrp == cpuctx->cgrp;
 +      /* @event doesn't care about cgroup */
 +      if (!event->cgrp)
 +              return true;
 +
 +      /* wants specific cgroup scope but @cpuctx isn't associated with any */
 +      if (!cpuctx->cgrp)
 +              return false;
 +
 +      /*
 +       * Cgroup scoping is recursive.  An event enabled for a cgroup is
 +       * also enabled for all its descendant cgroups.  If @cpuctx's
 +       * cgroup is a descendant of @event's (the test covers identity
 +       * case), it's a match.
 +       */
 +      return cgroup_is_descendant(cpuctx->cgrp->css.cgroup,
 +                                  event->cgrp->css.cgroup);
  }
  
  static inline bool perf_tryget_cgroup(struct perf_event *event)
@@@ -976,9 -976,15 +991,15 @@@ static void perf_event__header_size(str
        if (sample_type & PERF_SAMPLE_PERIOD)
                size += sizeof(data->period);
  
+       if (sample_type & PERF_SAMPLE_WEIGHT)
+               size += sizeof(data->weight);
        if (sample_type & PERF_SAMPLE_READ)
                size += event->read_size;
  
+       if (sample_type & PERF_SAMPLE_DATA_SRC)
+               size += sizeof(data->data_src.val);
        event->header_size = size;
  }
  
@@@ -4193,6 -4199,12 +4214,12 @@@ void perf_output_sample(struct perf_out
                perf_output_sample_ustack(handle,
                                          data->stack_user_size,
                                          data->regs_user.regs);
+       if (sample_type & PERF_SAMPLE_WEIGHT)
+               perf_output_put(handle, data->weight);
+       if (sample_type & PERF_SAMPLE_DATA_SRC)
+               perf_output_put(handle, data->data_src.val);
  }
  
  void perf_prepare_sample(struct perf_event_header *header,
@@@ -4611,7 -4623,6 +4638,7 @@@ void perf_event_comm(struct task_struc
        struct perf_event_context *ctx;
        int ctxn;
  
 +      rcu_read_lock();
        for_each_task_context_nr(ctxn) {
                ctx = task->perf_event_ctxp[ctxn];
                if (!ctx)
  
                perf_event_enable_on_exec(ctx);
        }
 +      rcu_read_unlock();
  
        if (!atomic_read(&nr_comm_events))
                return;
@@@ -4782,6 -4792,9 +4809,9 @@@ got_name
        mmap_event->file_name = name;
        mmap_event->file_size = size;
  
+       if (!(vma->vm_flags & VM_EXEC))
+               mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_DATA;
        mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size;
  
        rcu_read_lock();
@@@ -7532,5 -7545,12 +7562,5 @@@ struct cgroup_subsys perf_subsys = 
        .css_free       = perf_cgroup_css_free,
        .exit           = perf_cgroup_exit,
        .attach         = perf_cgroup_attach,
 -
 -      /*
 -       * perf_event cgroup doesn't handle nesting correctly.
 -       * ctx->nr_cgroups adjustments should be propagated through the
 -       * cgroup hierarchy.  Fix it and remove the following.
 -       */
 -      .broken_hierarchy = true,
  };
  #endif /* CONFIG_CGROUP_PERF */
diff --combined kernel/trace/trace.h
  #include <linux/trace_seq.h>
  #include <linux/ftrace_event.h>
  
 +#ifdef CONFIG_FTRACE_SYSCALLS
 +#include <asm/unistd.h>               /* For NR_SYSCALLS           */
 +#include <asm/syscall.h>      /* some archs define it here */
 +#endif
 +
  enum trace_type {
        __TRACE_FIRST_TYPE = 0,
  
@@@ -34,7 -29,6 +34,7 @@@
        TRACE_GRAPH_ENT,
        TRACE_USER_STACK,
        TRACE_BLK,
 +      TRACE_BPUTS,
  
        __TRACE_LAST_TYPE,
  };
@@@ -109,11 -103,6 +109,6 @@@ struct kretprobe_trace_entry_head 
        unsigned long           ret_ip;
  };
  
- struct uprobe_trace_entry_head {
-       struct trace_entry      ent;
-       unsigned long           ip;
- };
  /*
   * trace_flag_type is an enumeration that holds different
   * states when a trace occurs. These are:
@@@ -133,21 -122,12 +128,21 @@@ enum trace_flag_type 
  
  #define TRACE_BUF_SIZE                1024
  
 +struct trace_array;
 +
 +struct trace_cpu {
 +      struct trace_array      *tr;
 +      struct dentry           *dir;
 +      int                     cpu;
 +};
 +
  /*
   * The CPU trace array - it consists of thousands of trace entries
   * plus some other descriptor data: (for example which task started
   * the trace, etc.)
   */
  struct trace_array_cpu {
 +      struct trace_cpu        trace_cpu;
        atomic_t                disabled;
        void                    *buffer_page;   /* ring buffer spare */
  
        char                    comm[TASK_COMM_LEN];
  };
  
 +struct tracer;
 +
 +struct trace_buffer {
 +      struct trace_array              *tr;
 +      struct ring_buffer              *buffer;
 +      struct trace_array_cpu __percpu *data;
 +      cycle_t                         time_start;
 +      int                             cpu;
 +};
 +
  /*
   * The trace array - an array of per-CPU trace arrays. This is the
   * highest level data structure that individual tracers deal with.
   * They have on/off state as well:
   */
  struct trace_array {
 -      struct ring_buffer      *buffer;
 -      int                     cpu;
 +      struct list_head        list;
 +      char                    *name;
 +      struct trace_buffer     trace_buffer;
 +#ifdef CONFIG_TRACER_MAX_TRACE
 +      /*
 +       * The max_buffer is used to snapshot the trace when a maximum
 +       * latency is reached, or when the user initiates a snapshot.
 +       * Some tracers will use this to store a maximum trace while
 +       * it continues examining live traces.
 +       *
 +       * The buffers for the max_buffer are set up the same as the trace_buffer
 +       * When a snapshot is taken, the buffer of the max_buffer is swapped
 +       * with the buffer of the trace_buffer and the buffers are reset for
 +       * the trace_buffer so the tracing can continue.
 +       */
 +      struct trace_buffer     max_buffer;
 +      bool                    allocated_snapshot;
 +#endif
        int                     buffer_disabled;
 -      cycle_t                 time_start;
 +      struct trace_cpu        trace_cpu;      /* place holder */
 +#ifdef CONFIG_FTRACE_SYSCALLS
 +      int                     sys_refcount_enter;
 +      int                     sys_refcount_exit;
 +      DECLARE_BITMAP(enabled_enter_syscalls, NR_syscalls);
 +      DECLARE_BITMAP(enabled_exit_syscalls, NR_syscalls);
 +#endif
 +      int                     stop_count;
 +      int                     clock_id;
 +      struct tracer           *current_trace;
 +      unsigned int            flags;
 +      raw_spinlock_t          start_lock;
 +      struct dentry           *dir;
 +      struct dentry           *options;
 +      struct dentry           *percpu_dir;
 +      struct dentry           *event_dir;
 +      struct list_head        systems;
 +      struct list_head        events;
        struct task_struct      *waiter;
 -      struct trace_array_cpu  *data[NR_CPUS];
 +      int                     ref;
  };
  
 +enum {
 +      TRACE_ARRAY_FL_GLOBAL   = (1 << 0)
 +};
 +
 +extern struct list_head ftrace_trace_arrays;
 +
 +/*
 + * The global tracer (top) should be the first trace array added,
 + * but we check the flag anyway.
 + */
 +static inline struct trace_array *top_trace_array(void)
 +{
 +      struct trace_array *tr;
 +
 +      tr = list_entry(ftrace_trace_arrays.prev,
 +                      typeof(*tr), list);
 +      WARN_ON(!(tr->flags & TRACE_ARRAY_FL_GLOBAL));
 +      return tr;
 +}
 +
  #define FTRACE_CMP_TYPE(var, type) \
        __builtin_types_compatible_p(typeof(var), type *)
  
@@@ -278,7 -195,6 +273,7 @@@ extern void __ftrace_bad_type(void)
                IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\
                IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT);   \
                IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT); \
 +              IF_ASSIGN(var, ent, struct bputs_entry, TRACE_BPUTS);   \
                IF_ASSIGN(var, ent, struct trace_mmiotrace_rw,          \
                          TRACE_MMIO_RW);                               \
                IF_ASSIGN(var, ent, struct trace_mmiotrace_map,         \
@@@ -368,10 -284,9 +363,10 @@@ struct tracer 
        struct tracer           *next;
        struct tracer_flags     *flags;
        bool                    print_max;
 -      bool                    use_max_tr;
 -      bool                    allocated_snapshot;
        bool                    enabled;
 +#ifdef CONFIG_TRACER_MAX_TRACE
 +      bool                    use_max_tr;
 +#endif
  };
  
  
@@@ -507,6 -422,8 +502,6 @@@ static __always_inline void trace_clear
        current->trace_recursion = val;
  }
  
 -#define TRACE_PIPE_ALL_CPU    -1
 -
  static inline struct ring_buffer_iter *
  trace_buffer_iter(struct trace_iterator *iter, int cpu)
  {
  
  int tracer_init(struct tracer *t, struct trace_array *tr);
  int tracing_is_enabled(void);
 -void tracing_reset(struct trace_array *tr, int cpu);
 -void tracing_reset_online_cpus(struct trace_array *tr);
 +void tracing_reset(struct trace_buffer *buf, int cpu);
 +void tracing_reset_online_cpus(struct trace_buffer *buf);
  void tracing_reset_current(int cpu);
 -void tracing_reset_current_online_cpus(void);
 +void tracing_reset_all_online_cpus(void);
  int tracing_open_generic(struct inode *inode, struct file *filp);
  struct dentry *trace_create_file(const char *name,
                                 umode_t mode,
                                 void *data,
                                 const struct file_operations *fops);
  
 +struct dentry *tracing_init_dentry_tr(struct trace_array *tr);
  struct dentry *tracing_init_dentry(void);
  
  struct ring_buffer_event;
@@@ -662,7 -578,7 +657,7 @@@ extern int DYN_FTRACE_TEST_NAME(void)
  #define DYN_FTRACE_TEST_NAME2 trace_selftest_dynamic_test_func2
  extern int DYN_FTRACE_TEST_NAME2(void);
  
 -extern int ring_buffer_expanded;
 +extern bool ring_buffer_expanded;
  extern bool tracing_selftest_disabled;
  DECLARE_PER_CPU(int, ftrace_cpu_disabled);
  
@@@ -698,8 -614,6 +693,8 @@@ trace_array_vprintk(struct trace_array 
                    unsigned long ip, const char *fmt, va_list args);
  int trace_array_printk(struct trace_array *tr,
                       unsigned long ip, const char *fmt, ...);
 +int trace_array_printk_buf(struct ring_buffer *buffer,
 +                         unsigned long ip, const char *fmt, ...);
  void trace_printk_seq(struct trace_seq *s);
  enum print_line_t print_trace_line(struct trace_iterator *iter);
  
@@@ -867,7 -781,6 +862,7 @@@ enum trace_iterator_flags 
        TRACE_ITER_STOP_ON_FREE         = 0x400000,
        TRACE_ITER_IRQ_INFO             = 0x800000,
        TRACE_ITER_MARKERS              = 0x1000000,
 +      TRACE_ITER_FUNCTION             = 0x2000000,
  };
  
  /*
@@@ -914,8 -827,8 +909,8 @@@ enum 
  
  struct ftrace_event_field {
        struct list_head        link;
 -      char                    *name;
 -      char                    *type;
 +      const char              *name;
 +      const char              *type;
        int                     filter_type;
        int                     offset;
        int                     size;
@@@ -933,19 -846,12 +928,19 @@@ struct event_filter 
  struct event_subsystem {
        struct list_head        list;
        const char              *name;
 -      struct dentry           *entry;
        struct event_filter     *filter;
 -      int                     nr_events;
        int                     ref_count;
  };
  
 +struct ftrace_subsystem_dir {
 +      struct list_head                list;
 +      struct event_subsystem          *subsystem;
 +      struct trace_array              *tr;
 +      struct dentry                   *entry;
 +      int                             ref_count;
 +      int                             nr_events;
 +};
 +
  #define FILTER_PRED_INVALID   ((unsigned short)-1)
  #define FILTER_PRED_IS_RIGHT  (1 << 15)
  #define FILTER_PRED_FOLD      (1 << 15)
@@@ -995,20 -901,22 +990,20 @@@ struct filter_pred 
        unsigned short          right;
  };
  
 -extern struct list_head ftrace_common_fields;
 -
  extern enum regex_type
  filter_parse_regex(char *buff, int len, char **search, int *not);
  extern void print_event_filter(struct ftrace_event_call *call,
                               struct trace_seq *s);
  extern int apply_event_filter(struct ftrace_event_call *call,
                              char *filter_string);
 -extern int apply_subsystem_event_filter(struct event_subsystem *system,
 +extern int apply_subsystem_event_filter(struct ftrace_subsystem_dir *dir,
                                        char *filter_string);
  extern void print_subsystem_event_filter(struct event_subsystem *system,
                                         struct trace_seq *s);
  extern int filter_assign_type(const char *type);
  
 -struct list_head *
 -trace_get_fields(struct ftrace_event_call *event_call);
 +struct ftrace_event_field *
 +trace_find_event_field(struct ftrace_event_call *call, char *name);
  
  static inline int
  filter_check_discard(struct ftrace_event_call *call, void *rec,
  }
  
  extern void trace_event_enable_cmd_record(bool enable);
 +extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr);
 +extern int event_trace_del_tracer(struct trace_array *tr);
  
  extern struct mutex event_mutex;
  extern struct list_head ftrace_events;
@@@ -1037,18 -943,7 +1032,18 @@@ extern const char *__stop___trace_bprin
  void trace_printk_init_buffers(void);
  void trace_printk_start_comm(void);
  int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set);
 -int set_tracer_flag(unsigned int mask, int enabled);
 +int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled);
 +
 +/*
 + * Normal trace_printk() and friends allocates special buffers
 + * to do the manipulation, as well as saves the print formats
 + * into sections to display. But the trace infrastructure wants
 + * to use these without the added overhead at the price of being
 + * a bit slower (used mainly for warnings, where we don't care
 + * about performance). The internal_trace_puts() is for such
 + * a purpose.
 + */
 +#define internal_trace_puts(str) __trace_puts(_THIS_IP_, str, strlen(str))
  
  #undef FTRACE_ENTRY
  #define FTRACE_ENTRY(call, struct_name, id, tstruct, print, filter)   \