Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 Jul 2019 18:15:52 +0000 (11:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 Jul 2019 18:15:52 +0000 (11:15 -0700)
Pull perf updates from Ingo Molnar:
 "The main changes in this cycle on the kernel side were:

   - CPU PMU and uncore driver updates to Intel Snow Ridge, IceLake,
     KabyLake, AmberLake and WhiskeyLake CPUs.

   - Rework the MSR probing infrastructure to make it more robust, make
     it work better on virtualized systems and to better expose it on
     sysfs.

   - Rework PMU attributes group support based on the feedback from
     Greg. The core sysfs patch that adds sysfs_update_groups() was
     acked by Greg.

  There's a lot of perf tooling changes as well, all around the place:

   - vendor updates to Intel, cs-etm (ARM), ARM64, s390,

   - various enhancements to Intel PT tooling support:
      - Improve CBR (Core to Bus Ratio) packets support.
      - Export power and ptwrite events to sqlite and postgresql.
      - Add support for decoding PEBS via PT packets.
      - Add support for samples to contain IPC ratio, collecting cycles
        information from CYC packets, showing the IPC info periodically
      - Allow using time ranges

   - lots of updates to perf pmu, perf stat, perf trace, eBPF support,
     perf record, perf diff, etc. - please see the shortlog and Git log
     for details"

* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (252 commits)
  tools arch x86: Sync asm/cpufeatures.h with the with the kernel
  tools build: Check if gettid() is available before providing helper
  perf jvmti: Address gcc string overflow warning for strncpy()
  perf python: Remove -fstack-protector-strong if clang doesn't have it
  perf annotate TUI browser: Do not use member from variable within its own initialization
  perf tests: Fix record+probe_libc_inet_pton.sh for powerpc64
  perf evsel: Do not rely on errno values for precise_ip fallback
  perf thread: Allow references to thread objects after machine__exit()
  perf header: Assign proper ff->ph in perf_event__synthesize_features()
  tools arch kvm: Sync kvm headers with the kernel sources
  perf script: Allow specifying the files to process guest samples
  perf tools metric: Don't include duration_time in group
  perf list: Avoid extra : for --raw metrics
  perf vendor events intel: Metric fixes for SKX/CLX
  perf tools: Fix typos / broken sentences
  perf jevents: Add support for Hisi hip08 L3C PMU aliasing
  perf jevents: Add support for Hisi hip08 HHA PMU aliasing
  perf jevents: Add support for Hisi hip08 DDRC PMU aliasing
  perf pmu: Support more complex PMU event aliasing
  perf diff: Documentation -c cycles option
  ...

1  2 
arch/x86/events/core.c
kernel/events/core.c

diff --combined arch/x86/events/core.c
index ceb712b0a1c6b3a0f81fc0c80447870db673c21d,ffc015bd257e787469f40d5417d81b6d76e1077a..81b005e4c7d9f956e632b82cef9302976fc73e6c
@@@ -1618,68 -1618,6 +1618,6 @@@ static struct attribute_group x86_pmu_f
        .attrs = NULL,
  };
  
- /*
-  * Remove all undefined events (x86_pmu.event_map(id) == 0)
-  * out of events_attr attributes.
-  */
- static void __init filter_events(struct attribute **attrs)
- {
-       struct device_attribute *d;
-       struct perf_pmu_events_attr *pmu_attr;
-       int offset = 0;
-       int i, j;
-       for (i = 0; attrs[i]; i++) {
-               d = (struct device_attribute *)attrs[i];
-               pmu_attr = container_of(d, struct perf_pmu_events_attr, attr);
-               /* str trumps id */
-               if (pmu_attr->event_str)
-                       continue;
-               if (x86_pmu.event_map(i + offset))
-                       continue;
-               for (j = i; attrs[j]; j++)
-                       attrs[j] = attrs[j + 1];
-               /* Check the shifted attr. */
-               i--;
-               /*
-                * event_map() is index based, the attrs array is organized
-                * by increasing event index. If we shift the events, then
-                * we need to compensate for the event_map(), otherwise
-                * we are looking up the wrong event in the map
-                */
-               offset++;
-       }
- }
- /* Merge two pointer arrays */
- __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)
- {
-       struct attribute **new;
-       int j, i;
-       for (j = 0; a && a[j]; j++)
-               ;
-       for (i = 0; b && b[i]; i++)
-               j++;
-       j++;
-       new = kmalloc_array(j, sizeof(struct attribute *), GFP_KERNEL);
-       if (!new)
-               return NULL;
-       j = 0;
-       for (i = 0; a && a[i]; i++)
-               new[j++] = a[i];
-       for (i = 0; b && b[i]; i++)
-               new[j++] = b[i];
-       new[j] = NULL;
-       return new;
- }
  ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, char *page)
  {
        struct perf_pmu_events_attr *pmu_attr = \
@@@ -1744,9 -1682,24 +1682,24 @@@ static struct attribute *events_attr[] 
        NULL,
  };
  
+ /*
+  * Remove all undefined events (x86_pmu.event_map(id) == 0)
+  * out of events_attr attributes.
+  */
+ static umode_t
+ is_visible(struct kobject *kobj, struct attribute *attr, int idx)
+ {
+       struct perf_pmu_events_attr *pmu_attr;
+       pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr.attr);
+       /* str trumps id */
+       return pmu_attr->event_str || x86_pmu.event_map(idx) ? attr->mode : 0;
+ }
  static struct attribute_group x86_pmu_events_group __ro_after_init = {
        .name = "events",
        .attrs = events_attr,
+       .is_visible = is_visible,
  };
  
  ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event)
@@@ -1842,37 -1795,10 +1795,10 @@@ static int __init init_hw_perf_events(v
  
        x86_pmu_format_group.attrs = x86_pmu.format_attrs;
  
-       if (x86_pmu.caps_attrs) {
-               struct attribute **tmp;
-               tmp = merge_attr(x86_pmu_caps_group.attrs, x86_pmu.caps_attrs);
-               if (!WARN_ON(!tmp))
-                       x86_pmu_caps_group.attrs = tmp;
-       }
-       if (x86_pmu.event_attrs)
-               x86_pmu_events_group.attrs = x86_pmu.event_attrs;
        if (!x86_pmu.events_sysfs_show)
                x86_pmu_events_group.attrs = &empty_attrs;
-       else
-               filter_events(x86_pmu_events_group.attrs);
-       if (x86_pmu.cpu_events) {
-               struct attribute **tmp;
  
-               tmp = merge_attr(x86_pmu_events_group.attrs, x86_pmu.cpu_events);
-               if (!WARN_ON(!tmp))
-                       x86_pmu_events_group.attrs = tmp;
-       }
-       if (x86_pmu.attrs) {
-               struct attribute **tmp;
-               tmp = merge_attr(x86_pmu_attr_group.attrs, x86_pmu.attrs);
-               if (!WARN_ON(!tmp))
-                       x86_pmu_attr_group.attrs = tmp;
-       }
+       pmu.attr_update = x86_pmu.attr_update;
  
        pr_info("... version:                %d\n",     x86_pmu.version);
        pr_info("... bit width:              %d\n",     x86_pmu.cntval_bits);
@@@ -2179,7 -2105,7 +2105,7 @@@ static void x86_pmu_event_mapped(struc
         * For now, this can't happen because all callers hold mmap_sem
         * for write.  If this changes, we'll need a different solution.
         */
 -      lockdep_assert_held_exclusive(&mm->mmap_sem);
 +      lockdep_assert_held_write(&mm->mmap_sem);
  
        if (atomic_inc_return(&mm->context.perf_rdpmc_allowed) == 1)
                on_each_cpu_mask(mm_cpumask(mm), refresh_pce, NULL, 1);
diff --combined kernel/events/core.c
index 29e5f7880a4be1271ae65d7dbf5b829f37e4967c,ab52cf5103781685edc4fe20c26d49601a75e7ef..785d708f8553a001227a3259264d7b8fdccbcee8
@@@ -2952,6 -2952,12 +2952,12 @@@ static void ctx_sched_out(struct perf_e
        if (!ctx->nr_active || !(is_active & EVENT_ALL))
                return;
  
+       /*
+        * If we had been multiplexing, no rotations are necessary, now no events
+        * are active.
+        */
+       ctx->rotate_necessary = 0;
        perf_pmu_disable(ctx->pmu);
        if (is_active & EVENT_PINNED) {
                list_for_each_entry_safe(event, tmp, &ctx->pinned_active, active_list)
@@@ -3319,10 -3325,13 +3325,13 @@@ static int flexible_sched_in(struct per
                return 0;
  
        if (group_can_go_on(event, sid->cpuctx, sid->can_add_hw)) {
-               if (!group_sched_in(event, sid->cpuctx, sid->ctx))
-                       list_add_tail(&event->active_list, &sid->ctx->flexible_active);
-               else
+               int ret = group_sched_in(event, sid->cpuctx, sid->ctx);
+               if (ret) {
                        sid->can_add_hw = 0;
+                       sid->ctx->rotate_necessary = 1;
+                       return 0;
+               }
+               list_add_tail(&event->active_list, &sid->ctx->flexible_active);
        }
  
        return 0;
@@@ -3690,24 -3699,17 +3699,17 @@@ ctx_first_active(struct perf_event_cont
  static bool perf_rotate_context(struct perf_cpu_context *cpuctx)
  {
        struct perf_event *cpu_event = NULL, *task_event = NULL;
-       bool cpu_rotate = false, task_rotate = false;
-       struct perf_event_context *ctx = NULL;
+       struct perf_event_context *task_ctx = NULL;
+       int cpu_rotate, task_rotate;
  
        /*
         * Since we run this from IRQ context, nobody can install new
         * events, thus the event count values are stable.
         */
  
-       if (cpuctx->ctx.nr_events) {
-               if (cpuctx->ctx.nr_events != cpuctx->ctx.nr_active)
-                       cpu_rotate = true;
-       }
-       ctx = cpuctx->task_ctx;
-       if (ctx && ctx->nr_events) {
-               if (ctx->nr_events != ctx->nr_active)
-                       task_rotate = true;
-       }
+       cpu_rotate = cpuctx->ctx.rotate_necessary;
+       task_ctx = cpuctx->task_ctx;
+       task_rotate = task_ctx ? task_ctx->rotate_necessary : 0;
  
        if (!(cpu_rotate || task_rotate))
                return false;
        perf_pmu_disable(cpuctx->ctx.pmu);
  
        if (task_rotate)
-               task_event = ctx_first_active(ctx);
+               task_event = ctx_first_active(task_ctx);
        if (cpu_rotate)
                cpu_event = ctx_first_active(&cpuctx->ctx);
  
         * As per the order given at ctx_resched() first 'pop' task flexible
         * and then, if needed CPU flexible.
         */
-       if (task_event || (ctx && cpu_event))
-               ctx_sched_out(ctx, cpuctx, EVENT_FLEXIBLE);
+       if (task_event || (task_ctx && cpu_event))
+               ctx_sched_out(task_ctx, cpuctx, EVENT_FLEXIBLE);
        if (cpu_event)
                cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE);
  
        if (task_event)
-               rotate_ctx(ctx, task_event);
+               rotate_ctx(task_ctx, task_event);
        if (cpu_event)
                rotate_ctx(&cpuctx->ctx, cpu_event);
  
-       perf_event_sched_in(cpuctx, ctx, current);
+       perf_event_sched_in(cpuctx, task_ctx, current);
  
        perf_pmu_enable(cpuctx->ctx.pmu);
        perf_ctx_unlock(cpuctx, cpuctx->task_ctx);
@@@ -8535,9 -8537,9 +8537,9 @@@ static int perf_tp_event_match(struct p
        if (event->hw.state & PERF_HES_STOPPED)
                return 0;
        /*
-        * All tracepoints are from kernel-space.
+        * If exclude_kernel, only trace user-space tracepoints (uprobes)
         */
-       if (event->attr.exclude_kernel)
+       if (event->attr.exclude_kernel && !user_mode(regs))
                return 0;
  
        if (!perf_tp_filter_match(event, data))
@@@ -9877,6 -9879,12 +9879,12 @@@ static int pmu_dev_alloc(struct pmu *pm
        if (ret)
                goto del_dev;
  
+       if (pmu->attr_update)
+               ret = sysfs_update_groups(&pmu->dev->kobj, pmu->attr_update);
+       if (ret)
+               goto del_dev;
  out:
        return ret;
  
@@@ -10693,11 -10701,11 +10701,11 @@@ static int perf_event_set_clock(struct 
                break;
  
        case CLOCK_BOOTTIME:
 -              event->clock = &ktime_get_boot_ns;
 +              event->clock = &ktime_get_boottime_ns;
                break;
  
        case CLOCK_TAI:
 -              event->clock = &ktime_get_tai_ns;
 +              event->clock = &ktime_get_clocktai_ns;
                break;
  
        default: