Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 4 Nov 2018 01:13:43 +0000 (18:13 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 4 Nov 2018 01:13:43 +0000 (18:13 -0700)
Pull perf updates and fixes from Ingo Molnar:
 "These are almost all tooling updates: 'perf top', 'perf trace' and
  'perf script' fixes and updates, an UAPI header sync with the merge
  window versions, license marker updates, much improved Sparc support
  from David Miller, and a number of fixes"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (66 commits)
  perf intel-pt/bts: Calculate cpumode for synthesized samples
  perf intel-pt: Insert callchain context into synthesized callchains
  perf tools: Don't clone maps from parent when synthesizing forks
  perf top: Start display thread earlier
  tools headers uapi: Update linux/if_link.h header copy
  tools headers uapi: Update linux/netlink.h header copy
  tools headers: Sync the various kvm.h header copies
  tools include uapi: Update linux/mmap.h copy
  perf trace beauty: Use the mmap flags table generated from headers
  perf beauty: Wire up the mmap flags table generator to the Makefile
  perf beauty: Add a generator for MAP_ mmap's flag constants
  tools include uapi: Update asound.h copy
  tools arch uapi: Update asm-generic/unistd.h and arm64 unistd.h copies
  tools include uapi: Update linux/fs.h copy
  perf callchain: Honour the ordering of PERF_CONTEXT_{USER,KERNEL,etc}
  perf cs-etm: Correct CPU mode for samples
  perf unwind: Take pgoff into account when reporting elf to libdwfl
  perf top: Do not use overwrite mode by default
  perf top: Allow disabling the overwrite mode
  perf trace: Beautify mount's first pathname arg
  ...

1  2 
kernel/events/core.c
tools/perf/util/symbol-elf.c
tools/perf/util/symbol.h

diff --combined kernel/events/core.c
index 8c490130c4fb0072838801534948d9ec6b9a285f,65e90c752a91e7565128bb2ef723f29c678dde32..84530ab358c37ad876744d5ebda5d277dfb6d065
@@@ -750,7 -750,7 +750,7 @@@ static inline void update_cgrp_time_fro
        /*
         * Do not update time when cgroup is not active
         */
-        if (cgroup_is_descendant(cgrp->css.cgroup, event->cgrp->css.cgroup))
+       if (cgroup_is_descendant(cgrp->css.cgroup, event->cgrp->css.cgroup))
                __update_cgrp_time(event->cgrp);
  }
  
@@@ -8376,39 -8376,30 +8376,39 @@@ static struct pmu perf_tracepoint = 
   *
   * PERF_PROBE_CONFIG_IS_RETPROBE if set, create kretprobe/uretprobe
   *                               if not set, create kprobe/uprobe
 + *
 + * The following values specify a reference counter (or semaphore in the
 + * terminology of tools like dtrace, systemtap, etc.) Userspace Statically
 + * Defined Tracepoints (USDT). Currently, we use 40 bit for the offset.
 + *
 + * PERF_UPROBE_REF_CTR_OFFSET_BITS    # of bits in config as th offset
 + * PERF_UPROBE_REF_CTR_OFFSET_SHIFT   # of bits to shift left
   */
  enum perf_probe_config {
        PERF_PROBE_CONFIG_IS_RETPROBE = 1U << 0,  /* [k,u]retprobe */
 +      PERF_UPROBE_REF_CTR_OFFSET_BITS = 32,
 +      PERF_UPROBE_REF_CTR_OFFSET_SHIFT = 64 - PERF_UPROBE_REF_CTR_OFFSET_BITS,
  };
  
  PMU_FORMAT_ATTR(retprobe, "config:0");
 +#endif
  
 -static struct attribute *probe_attrs[] = {
 +#ifdef CONFIG_KPROBE_EVENTS
 +static struct attribute *kprobe_attrs[] = {
        &format_attr_retprobe.attr,
        NULL,
  };
  
 -static struct attribute_group probe_format_group = {
 +static struct attribute_group kprobe_format_group = {
        .name = "format",
 -      .attrs = probe_attrs,
 +      .attrs = kprobe_attrs,
  };
  
 -static const struct attribute_group *probe_attr_groups[] = {
 -      &probe_format_group,
 +static const struct attribute_group *kprobe_attr_groups[] = {
 +      &kprobe_format_group,
        NULL,
  };
 -#endif
  
 -#ifdef CONFIG_KPROBE_EVENTS
  static int perf_kprobe_event_init(struct perf_event *event);
  static struct pmu perf_kprobe = {
        .task_ctx_nr    = perf_sw_context,
        .start          = perf_swevent_start,
        .stop           = perf_swevent_stop,
        .read           = perf_swevent_read,
 -      .attr_groups    = probe_attr_groups,
 +      .attr_groups    = kprobe_attr_groups,
  };
  
  static int perf_kprobe_event_init(struct perf_event *event)
  #endif /* CONFIG_KPROBE_EVENTS */
  
  #ifdef CONFIG_UPROBE_EVENTS
 +PMU_FORMAT_ATTR(ref_ctr_offset, "config:32-63");
 +
 +static struct attribute *uprobe_attrs[] = {
 +      &format_attr_retprobe.attr,
 +      &format_attr_ref_ctr_offset.attr,
 +      NULL,
 +};
 +
 +static struct attribute_group uprobe_format_group = {
 +      .name = "format",
 +      .attrs = uprobe_attrs,
 +};
 +
 +static const struct attribute_group *uprobe_attr_groups[] = {
 +      &uprobe_format_group,
 +      NULL,
 +};
 +
  static int perf_uprobe_event_init(struct perf_event *event);
  static struct pmu perf_uprobe = {
        .task_ctx_nr    = perf_sw_context,
        .start          = perf_swevent_start,
        .stop           = perf_swevent_stop,
        .read           = perf_swevent_read,
 -      .attr_groups    = probe_attr_groups,
 +      .attr_groups    = uprobe_attr_groups,
  };
  
  static int perf_uprobe_event_init(struct perf_event *event)
  {
        int err;
 +      unsigned long ref_ctr_offset;
        bool is_retprobe;
  
        if (event->attr.type != perf_uprobe.type)
                return -EOPNOTSUPP;
  
        is_retprobe = event->attr.config & PERF_PROBE_CONFIG_IS_RETPROBE;
 -      err = perf_uprobe_init(event, is_retprobe);
 +      ref_ctr_offset = event->attr.config >> PERF_UPROBE_REF_CTR_OFFSET_SHIFT;
 +      err = perf_uprobe_init(event, ref_ctr_offset, is_retprobe);
        if (err)
                return err;
  
index 0281d5e2cd6703d0d0d34562a602b8d780b88926,6e70cc00c161871defd9fea28d1b96812c3025b4..66a84d5846c88ed912aff027943c6f8e9ff78ff2
@@@ -324,7 -324,17 +324,17 @@@ int dso__synthesize_plt_symbols(struct 
                        plt_entry_size = 16;
                        break;
  
-               default: /* FIXME: s390/alpha/mips/parisc/poperpc/sh/sparc/xtensa need to be checked */
+               case EM_SPARC:
+                       plt_header_size = 48;
+                       plt_entry_size = 12;
+                       break;
+               case EM_SPARCV9:
+                       plt_header_size = 128;
+                       plt_entry_size = 32;
+                       break;
+               default: /* FIXME: s390/alpha/mips/parisc/poperpc/sh/xtensa need to be checked */
                        plt_header_size = shdr_plt.sh_entsize;
                        plt_entry_size = shdr_plt.sh_entsize;
                        break;
@@@ -1947,34 -1957,6 +1957,34 @@@ void kcore_extract__delete(struct kcore
  }
  
  #ifdef HAVE_GELF_GETNOTE_SUPPORT
 +
 +static void sdt_adjust_loc(struct sdt_note *tmp, GElf_Addr base_off)
 +{
 +      if (!base_off)
 +              return;
 +
 +      if (tmp->bit32)
 +              tmp->addr.a32[SDT_NOTE_IDX_LOC] =
 +                      tmp->addr.a32[SDT_NOTE_IDX_LOC] + base_off -
 +                      tmp->addr.a32[SDT_NOTE_IDX_BASE];
 +      else
 +              tmp->addr.a64[SDT_NOTE_IDX_LOC] =
 +                      tmp->addr.a64[SDT_NOTE_IDX_LOC] + base_off -
 +                      tmp->addr.a64[SDT_NOTE_IDX_BASE];
 +}
 +
 +static void sdt_adjust_refctr(struct sdt_note *tmp, GElf_Addr base_addr,
 +                            GElf_Addr base_off)
 +{
 +      if (!base_off)
 +              return;
 +
 +      if (tmp->bit32 && tmp->addr.a32[SDT_NOTE_IDX_REFCTR])
 +              tmp->addr.a32[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
 +      else if (tmp->addr.a64[SDT_NOTE_IDX_REFCTR])
 +              tmp->addr.a64[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
 +}
 +
  /**
   * populate_sdt_note : Parse raw data and identify SDT note
   * @elf: elf of the opened file
@@@ -1992,6 -1974,7 +2002,6 @@@ static int populate_sdt_note(Elf **elf
        const char *provider, *name, *args;
        struct sdt_note *tmp = NULL;
        GElf_Ehdr ehdr;
 -      GElf_Addr base_off = 0;
        GElf_Shdr shdr;
        int ret = -EINVAL;
  
         * base address in the description of the SDT note. If its different,
         * then accordingly, adjust the note location.
         */
 -      if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL)) {
 -              base_off = shdr.sh_offset;
 -              if (base_off) {
 -                      if (tmp->bit32)
 -                              tmp->addr.a32[0] = tmp->addr.a32[0] + base_off -
 -                                      tmp->addr.a32[1];
 -                      else
 -                              tmp->addr.a64[0] = tmp->addr.a64[0] + base_off -
 -                                      tmp->addr.a64[1];
 -              }
 -      }
 +      if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL))
 +              sdt_adjust_loc(tmp, shdr.sh_offset);
 +
 +      /* Adjust reference counter offset */
 +      if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_PROBES_SCN, NULL))
 +              sdt_adjust_refctr(tmp, shdr.sh_addr, shdr.sh_offset);
  
        list_add_tail(&tmp->note_list, sdt_notes);
        return 0;
diff --combined tools/perf/util/symbol.h
index 20f49779116bd3ad7b98991688cc1cf4201e444c,d726a8a7bb1b07fc0d8e5b450ac82d71c72e51f1..d026d215bdc63244638c26e4ac4586fa8fe3a1cb
@@@ -123,7 -123,8 +123,8 @@@ struct symbol_conf 
        const char      *vmlinux_name,
                        *kallsyms_name,
                        *source_prefix,
-                       *field_sep;
+                       *field_sep,
+                       *graph_function;
        const char      *default_guest_vmlinux_name,
                        *default_guest_kallsyms,
                        *default_guest_modules;
@@@ -379,19 -380,12 +380,19 @@@ int get_sdt_note_list(struct list_head 
  int cleanup_sdt_note_list(struct list_head *sdt_notes);
  int sdt_notes__get_count(struct list_head *start);
  
 +#define SDT_PROBES_SCN ".probes"
  #define SDT_BASE_SCN ".stapsdt.base"
  #define SDT_NOTE_SCN  ".note.stapsdt"
  #define SDT_NOTE_TYPE 3
  #define SDT_NOTE_NAME "stapsdt"
  #define NR_ADDR 3
  
 +enum {
 +      SDT_NOTE_IDX_LOC = 0,
 +      SDT_NOTE_IDX_BASE,
 +      SDT_NOTE_IDX_REFCTR,
 +};
 +
  struct mem_info *mem_info__new(void);
  struct mem_info *mem_info__get(struct mem_info *mi);
  void   mem_info__put(struct mem_info *mi);