Merge tag 'v5.2' into perf/core, to pick up fixes
authorIngo Molnar <mingo@kernel.org>
Mon, 8 Jul 2019 16:04:41 +0000 (18:04 +0200)
committerIngo Molnar <mingo@kernel.org>
Mon, 8 Jul 2019 16:04:41 +0000 (18:04 +0200)
Signed-off-by: Ingo Molnar <mingo@kernel.org>
1  2 
MAINTAINERS
arch/x86/events/core.c
arch/x86/events/perf_event.h
include/linux/perf_event.h
kernel/events/core.c

diff --combined MAINTAINERS
index 4be48eb5473d3ef4c6d8d44e50b6f189717acdcb,677ef41cb012ca2a3f4fb9ee56bdc45c450ff6cc..c80bd74681ccb6a47ed6d8ecaf9145713257e892
@@@ -3122,6 -3122,7 +3122,7 @@@ F:      arch/arm/mach-bcm
  BROADCOM BCM2835 ARM ARCHITECTURE
  M:    Eric Anholt <eric@anholt.net>
  M:    Stefan Wahren <wahrenst@gmx.net>
+ L:    bcm-kernel-feedback-list@broadcom.com
  L:    linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers)
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  T:    git git://github.com/anholt/linux
@@@ -3151,6 -3152,7 +3152,7 @@@ F:      arch/arm/boot/dts/bcm953012
  
  BROADCOM BCM53573 ARM ARCHITECTURE
  M:    Rafał Miłecki <rafal@milecki.pl>
+ L:    bcm-kernel-feedback-list@broadcom.com
  L:    linux-arm-kernel@lists.infradead.org
  S:    Maintained
  F:    arch/arm/boot/dts/bcm53573*
@@@ -3940,6 -3942,14 +3942,14 @@@ M:    Miguel Ojeda <miguel.ojeda.sandonis@
  S:    Maintained
  F:    .clang-format
  
+ CLANG/LLVM BUILD SUPPORT
+ L:    clang-built-linux@googlegroups.com
+ W:    https://clangbuiltlinux.github.io/
+ B:    https://github.com/ClangBuiltLinux/linux/issues
+ C:    irc://chat.freenode.net/clangbuiltlinux
+ S:    Supported
+ K:    \b(?i:clang|llvm)\b
  CLEANCACHE API
  M:    Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
  L:    linux-kernel@vger.kernel.org
@@@ -7800,7 -7810,7 +7810,7 @@@ INGENIC JZ4780 NAND DRIVE
  M:    Harvey Hunt <harveyhuntnexus@gmail.com>
  L:    linux-mtd@lists.infradead.org
  S:    Maintained
- F:    drivers/mtd/nand/raw/jz4780_*
+ F:    drivers/mtd/nand/raw/ingenic/
  
  INOTIFY
  M:    Jan Kara <jack@suse.cz>
@@@ -15493,6 -15503,7 +15503,7 @@@ F:   drivers/dma/tegra
  
  TEGRA I2C DRIVER
  M:    Laxman Dewangan <ldewangan@nvidia.com>
+ R:    Dmitry Osipenko <digetx@gmail.com>
  S:    Supported
  F:    drivers/i2c/busses/i2c-tegra.c
  
@@@ -17485,12 -17496,6 +17496,12 @@@ Q: https://patchwork.linuxtv.org/projec
  S:    Maintained
  F:    drivers/media/dvb-frontends/zd1301_demod*
  
 +ZHAOXIN PROCESSOR SUPPORT
 +M:    Tony W Wang-oc <TonyWWang-oc@zhaoxin.com>
 +L:    linux-kernel@vger.kernel.org
 +S:    Maintained
 +F:    arch/x86/kernel/cpu/zhaoxin.c
 +
  ZPOOL COMPRESSED PAGE STORAGE API
  M:    Dan Streetman <ddstreet@ieee.org>
  L:    linux-mm@kvack.org
diff --combined arch/x86/events/core.c
index f0e4804515d8f6c44b8d9720b6cd0a412acbd630,3cd94a21bd539af6de18d97b4ff0727a0468dfaf..ffc015bd257e787469f40d5417d81b6d76e1077a
@@@ -561,14 -561,14 +561,14 @@@ int x86_pmu_hw_config(struct perf_even
        }
  
        /* sample_regs_user never support XMM registers */
-       if (unlikely(event->attr.sample_regs_user & PEBS_XMM_REGS))
+       if (unlikely(event->attr.sample_regs_user & PERF_REG_EXTENDED_MASK))
                return -EINVAL;
        /*
         * Besides the general purpose registers, XMM registers may
         * be collected in PEBS on some platforms, e.g. Icelake
         */
-       if (unlikely(event->attr.sample_regs_intr & PEBS_XMM_REGS)) {
-               if (x86_pmu.pebs_no_xmm_regs)
+       if (unlikely(event->attr.sample_regs_intr & PERF_REG_EXTENDED_MASK)) {
+               if (!(event->pmu->capabilities & PERF_PMU_CAP_EXTENDED_REGS))
                        return -EINVAL;
  
                if (!event->attr.precise_ip)
@@@ -1618,6 -1618,68 +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 = \
@@@ -1682,24 -1744,9 +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)
@@@ -1795,10 -1842,37 +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);
@@@ -2328,13 -2402,13 +2328,13 @@@ perf_callchain_kernel(struct perf_callc
                return;
        }
  
-       if (perf_hw_regs(regs)) {
-               if (perf_callchain_store(entry, regs->ip))
-                       return;
+       if (perf_callchain_store(entry, regs->ip))
+               return;
+       if (perf_hw_regs(regs))
                unwind_start(&state, current, regs, NULL);
-       } else {
+       else
                unwind_start(&state, current, NULL, (void *)regs->sp);
-       }
  
        for (; !unwind_done(&state); unwind_next_frame(&state)) {
                addr = unwind_get_return_address(&state);
index 9bcec3f99e4aa270f8751bd7bb04c40d5f90faab,4e346856ee195528c418cba4d791942fc706d8c7..8751008fc1703d231168ebfbcd4b1ed1107bb6f7
@@@ -121,24 -121,6 +121,6 @@@ struct amd_nb 
         (1ULL << PERF_REG_X86_R14)   | \
         (1ULL << PERF_REG_X86_R15))
  
- #define PEBS_XMM_REGS                   \
-       ((1ULL << PERF_REG_X86_XMM0)  | \
-        (1ULL << PERF_REG_X86_XMM1)  | \
-        (1ULL << PERF_REG_X86_XMM2)  | \
-        (1ULL << PERF_REG_X86_XMM3)  | \
-        (1ULL << PERF_REG_X86_XMM4)  | \
-        (1ULL << PERF_REG_X86_XMM5)  | \
-        (1ULL << PERF_REG_X86_XMM6)  | \
-        (1ULL << PERF_REG_X86_XMM7)  | \
-        (1ULL << PERF_REG_X86_XMM8)  | \
-        (1ULL << PERF_REG_X86_XMM9)  | \
-        (1ULL << PERF_REG_X86_XMM10) | \
-        (1ULL << PERF_REG_X86_XMM11) | \
-        (1ULL << PERF_REG_X86_XMM12) | \
-        (1ULL << PERF_REG_X86_XMM13) | \
-        (1ULL << PERF_REG_X86_XMM14) | \
-        (1ULL << PERF_REG_X86_XMM15))
  /*
   * Per register state.
   */
@@@ -631,11 -613,14 +613,11 @@@ struct x86_pmu 
        int             attr_rdpmc_broken;
        int             attr_rdpmc;
        struct attribute **format_attrs;
 -      struct attribute **event_attrs;
 -      struct attribute **caps_attrs;
  
        ssize_t         (*events_sysfs_show)(char *page, u64 config);
 -      struct attribute **cpu_events;
 +      const struct attribute_group **attr_update;
  
        unsigned long   attr_freeze_on_smi;
 -      struct attribute **attrs;
  
        /*
         * CPU Hotplug hooks
                        pebs_broken             :1,
                        pebs_prec_dist          :1,
                        pebs_no_tlb             :1,
-                       pebs_no_isolation       :1,
-                       pebs_no_xmm_regs        :1;
+                       pebs_no_isolation       :1;
        int             pebs_record_size;
        int             pebs_buffer_size;
        int             max_pebs_events;
@@@ -902,6 -886,8 +883,6 @@@ static inline void set_linear_ip(struc
  ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event);
  ssize_t intel_event_sysfs_show(char *page, u64 config);
  
 -struct attribute **merge_attr(struct attribute **a, struct attribute **b);
 -
  ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr,
                          char *page);
  ssize_t events_ht_sysfs_show(struct device *dev, struct device_attribute *attr,
index 2ddae518dce64a54b73c175ee40721d04f5032ad,2bca72f3028b6310c59a14df026bfe6dc480c38c..16e38c286d46be1f608dbcfd88e3dd5f383a78e4
@@@ -241,6 -241,7 +241,7 @@@ struct perf_event
  #define PERF_PMU_CAP_NO_INTERRUPT             0x01
  #define PERF_PMU_CAP_NO_NMI                   0x02
  #define PERF_PMU_CAP_AUX_NO_SG                        0x04
+ #define PERF_PMU_CAP_EXTENDED_REGS            0x08
  #define PERF_PMU_CAP_EXCLUSIVE                        0x10
  #define PERF_PMU_CAP_ITRACE                   0x20
  #define PERF_PMU_CAP_HETEROGENEOUS_CPUS               0x40
@@@ -255,7 -256,6 +256,7 @@@ struct pmu 
        struct module                   *module;
        struct device                   *dev;
        const struct attribute_group    **attr_groups;
 +      const struct attribute_group    **attr_update;
        const char                      *name;
        int                             type;
  
@@@ -749,11 -749,6 +750,11 @@@ struct perf_event_context 
        int                             nr_stat;
        int                             nr_freq;
        int                             rotate_disable;
 +      /*
 +       * Set when nr_events != nr_active, except tolerant to events not
 +       * necessary to be active due to scheduling constraints, such as cgroups.
 +       */
 +      int                             rotate_necessary;
        refcount_t                      refcount;
        struct task_struct              *task;
  
diff --combined kernel/events/core.c
index 23efe6792abcc3d4bf7ab2c0d2cb028ef618d5d4,f85929ce13be6e4780ca7f8dce44f9024da76688..ab52cf5103781685edc4fe20c26d49601a75e7ef
@@@ -2952,12 -2952,6 +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)
@@@ -3325,13 -3319,10 +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;
@@@ -3699,17 -3690,24 +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);
@@@ -5007,6 -5005,9 +5007,9 @@@ static int perf_event_period(struct per
        if (perf_event_check_period(event, value))
                return -EINVAL;
  
+       if (!event->attr.freq && (value & (1ULL << 63)))
+               return -EINVAL;
        event_function_call(event, __perf_event_period, &value);
  
        return 0;
@@@ -5925,7 -5926,7 +5928,7 @@@ static void perf_sample_regs_user(struc
        if (user_mode(regs)) {
                regs_user->abi = perf_reg_abi(current);
                regs_user->regs = regs;
-       } else if (current->mm) {
+       } else if (!(current->flags & PF_KTHREAD)) {
                perf_get_regs_user(regs_user, regs, regs_user_copy);
        } else {
                regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE;
@@@ -8534,9 -8535,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))
@@@ -9876,12 -9877,6 +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;
  
@@@ -10041,6 -10036,12 +10044,12 @@@ void perf_pmu_unregister(struct pmu *pm
  }
  EXPORT_SYMBOL_GPL(perf_pmu_unregister);
  
+ static inline bool has_extended_regs(struct perf_event *event)
+ {
+       return (event->attr.sample_regs_user & PERF_REG_EXTENDED_MASK) ||
+              (event->attr.sample_regs_intr & PERF_REG_EXTENDED_MASK);
+ }
  static int perf_try_init_event(struct pmu *pmu, struct perf_event *event)
  {
        struct perf_event_context *ctx = NULL;
                perf_event_ctx_unlock(event->group_leader, ctx);
  
        if (!ret) {
+               if (!(pmu->capabilities & PERF_PMU_CAP_EXTENDED_REGS) &&
+                   has_extended_regs(event))
+                       ret = -EOPNOTSUPP;
                if (pmu->capabilities & PERF_PMU_CAP_NO_EXCLUDE &&
-                               event_has_any_exclude_flag(event)) {
-                       if (event->destroy)
-                               event->destroy(event);
+                   event_has_any_exclude_flag(event))
                        ret = -EINVAL;
-               }
+               if (ret && event->destroy)
+                       event->destroy(event);
        }
  
        if (ret)