]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-tip' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile...
authorIngo Molnar <mingo@kernel.org>
Mon, 8 Apr 2013 09:43:30 +0000 (11:43 +0200)
committerIngo Molnar <mingo@kernel.org>
Mon, 8 Apr 2013 09:43:30 +0000 (11:43 +0200)
Pull IBM zEnterprise EC12 support patchlet from Robert Richter.

Signed-off-by: Ingo Molnar <mingo@kernel.org>
1  2 
Makefile
arch/x86/include/uapi/asm/msr-index.h
arch/x86/kernel/cpu/perf_event_intel_ds.c
include/linux/perf_event.h

diff --combined Makefile
index 6b39246c2c67dd6c8e56b82d0b32da67e45c3d67,58a165b02af1e27acb6d2635f3c9ab0d58c5cb00..70fd2748388722418ad00a683f5b9bfb8382fe8d
+++ b/Makefile
@@@ -1,7 -1,7 +1,7 @@@
  VERSION = 3
  PATCHLEVEL = 9
  SUBLEVEL = 0
- EXTRAVERSION = -rc2
+ EXTRAVERSION = -rc5
  NAME = Unicycling Gorilla
  
  # *DOCUMENTATION*
@@@ -1331,11 -1331,11 +1331,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
  # ---------------------------------------------------------------------------
index b31798d5e62e99713aae25a67a58e140065ca48c,7a060f4b411f753ed065c389b705e7b2a010ab7b..bf7bb68f43a8203f66839dc3e72dc2ef39b7320c
@@@ -44,6 -44,7 +44,7 @@@
  #define SNB_C1_AUTO_UNDEMOTE          (1UL << 27)
  #define SNB_C3_AUTO_UNDEMOTE          (1UL << 28)
  
+ #define MSR_PLATFORM_INFO             0x000000ce
  #define MSR_MTRRcap                   0x000000fe
  #define MSR_IA32_BBL_CR_CTL           0x00000119
  #define MSR_IA32_BBL_CR_CTL3          0x0000011e
@@@ -71,7 -72,6 +72,7 @@@
  #define MSR_IA32_PEBS_ENABLE          0x000003f1
  #define MSR_IA32_DS_AREA              0x00000600
  #define MSR_IA32_PERF_CAPABILITIES    0x00000345
 +#define MSR_PEBS_LD_LAT_THRESHOLD     0x000003f6
  
  #define MSR_MTRRfix64K_00000          0x00000250
  #define MSR_MTRRfix16K_80000          0x00000258
index 36dc13d1ad02de985f15dce46d47ff326e9036d7,b05a575d56f42f4543504b999a3b4875de110772..d467561c805fd7da302dbf6824e0c57df8b69106
@@@ -24,130 -24,6 +24,130 @@@ struct pebs_record_32 
  
   */
  
 +union intel_x86_pebs_dse {
 +      u64 val;
 +      struct {
 +              unsigned int ld_dse:4;
 +              unsigned int ld_stlb_miss:1;
 +              unsigned int ld_locked:1;
 +              unsigned int ld_reserved:26;
 +      };
 +      struct {
 +              unsigned int st_l1d_hit:1;
 +              unsigned int st_reserved1:3;
 +              unsigned int st_stlb_miss:1;
 +              unsigned int st_locked:1;
 +              unsigned int st_reserved2:26;
 +      };
 +};
 +
 +
 +/*
 + * Map PEBS Load Latency Data Source encodings to generic
 + * memory data source information
 + */
 +#define P(a, b) PERF_MEM_S(a, b)
 +#define OP_LH (P(OP, LOAD) | P(LVL, HIT))
 +#define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS))
 +
 +static const u64 pebs_data_source[] = {
 +      P(OP, LOAD) | P(LVL, MISS) | P(LVL, L3) | P(SNOOP, NA),/* 0x00:ukn L3 */
 +      OP_LH | P(LVL, L1)  | P(SNOOP, NONE),   /* 0x01: L1 local */
 +      OP_LH | P(LVL, LFB) | P(SNOOP, NONE),   /* 0x02: LFB hit */
 +      OP_LH | P(LVL, L2)  | P(SNOOP, NONE),   /* 0x03: L2 hit */
 +      OP_LH | P(LVL, L3)  | P(SNOOP, NONE),   /* 0x04: L3 hit */
 +      OP_LH | P(LVL, L3)  | P(SNOOP, MISS),   /* 0x05: L3 hit, snoop miss */
 +      OP_LH | P(LVL, L3)  | P(SNOOP, HIT),    /* 0x06: L3 hit, snoop hit */
 +      OP_LH | P(LVL, L3)  | P(SNOOP, HITM),   /* 0x07: L3 hit, snoop hitm */
 +      OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HIT),  /* 0x08: L3 miss snoop hit */
 +      OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HITM), /* 0x09: L3 miss snoop hitm*/
 +      OP_LH | P(LVL, LOC_RAM)  | P(SNOOP, HIT),  /* 0x0a: L3 miss, shared */
 +      OP_LH | P(LVL, REM_RAM1) | P(SNOOP, HIT),  /* 0x0b: L3 miss, shared */
 +      OP_LH | P(LVL, LOC_RAM)  | SNOOP_NONE_MISS,/* 0x0c: L3 miss, excl */
 +      OP_LH | P(LVL, REM_RAM1) | SNOOP_NONE_MISS,/* 0x0d: L3 miss, excl */
 +      OP_LH | P(LVL, IO)  | P(SNOOP, NONE), /* 0x0e: I/O */
 +      OP_LH | P(LVL, UNC) | P(SNOOP, NONE), /* 0x0f: uncached */
 +};
 +
 +static u64 precise_store_data(u64 status)
 +{
 +      union intel_x86_pebs_dse dse;
 +      u64 val = P(OP, STORE) | P(SNOOP, NA) | P(LVL, L1) | P(TLB, L2);
 +
 +      dse.val = status;
 +
 +      /*
 +       * bit 4: TLB access
 +       * 1 = stored missed 2nd level TLB
 +       *
 +       * so it either hit the walker or the OS
 +       * otherwise hit 2nd level TLB
 +       */
 +      if (dse.st_stlb_miss)
 +              val |= P(TLB, MISS);
 +      else
 +              val |= P(TLB, HIT);
 +
 +      /*
 +       * bit 0: hit L1 data cache
 +       * if not set, then all we know is that
 +       * it missed L1D
 +       */
 +      if (dse.st_l1d_hit)
 +              val |= P(LVL, HIT);
 +      else
 +              val |= P(LVL, MISS);
 +
 +      /*
 +       * bit 5: Locked prefix
 +       */
 +      if (dse.st_locked)
 +              val |= P(LOCK, LOCKED);
 +
 +      return val;
 +}
 +
 +static u64 load_latency_data(u64 status)
 +{
 +      union intel_x86_pebs_dse dse;
 +      u64 val;
 +      int model = boot_cpu_data.x86_model;
 +      int fam = boot_cpu_data.x86;
 +
 +      dse.val = status;
 +
 +      /*
 +       * use the mapping table for bit 0-3
 +       */
 +      val = pebs_data_source[dse.ld_dse];
 +
 +      /*
 +       * Nehalem models do not support TLB, Lock infos
 +       */
 +      if (fam == 0x6 && (model == 26 || model == 30
 +          || model == 31 || model == 46)) {
 +              val |= P(TLB, NA) | P(LOCK, NA);
 +              return val;
 +      }
 +      /*
 +       * bit 4: TLB access
 +       * 0 = did not miss 2nd level TLB
 +       * 1 = missed 2nd level TLB
 +       */
 +      if (dse.ld_stlb_miss)
 +              val |= P(TLB, MISS) | P(TLB, L2);
 +      else
 +              val |= P(TLB, HIT) | P(TLB, L1) | P(TLB, L2);
 +
 +      /*
 +       * bit 5: locked prefix
 +       */
 +      if (dse.ld_locked)
 +              val |= P(LOCK, LOCKED);
 +
 +      return val;
 +}
 +
  struct pebs_record_core {
        u64 flags, ip;
        u64 ax, bx, cx, dx;
@@@ -488,7 -364,7 +488,7 @@@ struct event_constraint intel_atom_pebs
  };
  
  struct event_constraint intel_nehalem_pebs_event_constraints[] = {
 -      INTEL_EVENT_CONSTRAINT(0x0b, 0xf),    /* MEM_INST_RETIRED.* */
 +      INTEL_PLD_CONSTRAINT(0x100b, 0xf),      /* MEM_INST_RETIRED.* */
        INTEL_EVENT_CONSTRAINT(0x0f, 0xf),    /* MEM_UNCORE_RETIRED.* */
        INTEL_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */
        INTEL_EVENT_CONSTRAINT(0xc0, 0xf),    /* INST_RETIRED.ANY */
  };
  
  struct event_constraint intel_westmere_pebs_event_constraints[] = {
 -      INTEL_EVENT_CONSTRAINT(0x0b, 0xf),    /* MEM_INST_RETIRED.* */
 +      INTEL_PLD_CONSTRAINT(0x100b, 0xf),      /* MEM_INST_RETIRED.* */
        INTEL_EVENT_CONSTRAINT(0x0f, 0xf),    /* MEM_UNCORE_RETIRED.* */
        INTEL_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */
        INTEL_EVENT_CONSTRAINT(0xc0, 0xf),    /* INSTR_RETIRED.* */
@@@ -523,8 -399,7 +523,8 @@@ struct event_constraint intel_snb_pebs_
        INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */
        INTEL_EVENT_CONSTRAINT(0xc4, 0xf),    /* BR_INST_RETIRED.* */
        INTEL_EVENT_CONSTRAINT(0xc5, 0xf),    /* BR_MISP_RETIRED.* */
 -      INTEL_EVENT_CONSTRAINT(0xcd, 0x8),    /* MEM_TRANS_RETIRED.* */
 +      INTEL_PLD_CONSTRAINT(0x01cd, 0x8),    /* MEM_TRANS_RETIRED.LAT_ABOVE_THR */
 +      INTEL_PST_CONSTRAINT(0x02cd, 0x8),    /* MEM_TRANS_RETIRED.PRECISE_STORES */
        INTEL_EVENT_CONSTRAINT(0xd0, 0xf),    /* MEM_UOP_RETIRED.* */
        INTEL_EVENT_CONSTRAINT(0xd1, 0xf),    /* MEM_LOAD_UOPS_RETIRED.* */
        INTEL_EVENT_CONSTRAINT(0xd2, 0xf),    /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
@@@ -538,8 -413,7 +538,8 @@@ struct event_constraint intel_ivb_pebs_
          INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */
          INTEL_EVENT_CONSTRAINT(0xc4, 0xf),    /* BR_INST_RETIRED.* */
          INTEL_EVENT_CONSTRAINT(0xc5, 0xf),    /* BR_MISP_RETIRED.* */
 -        INTEL_EVENT_CONSTRAINT(0xcd, 0x8),    /* MEM_TRANS_RETIRED.* */
 +        INTEL_PLD_CONSTRAINT(0x01cd, 0x8),    /* MEM_TRANS_RETIRED.LAT_ABOVE_THR */
 +      INTEL_PST_CONSTRAINT(0x02cd, 0x8),    /* MEM_TRANS_RETIRED.PRECISE_STORES */
          INTEL_EVENT_CONSTRAINT(0xd0, 0xf),    /* MEM_UOP_RETIRED.* */
          INTEL_EVENT_CONSTRAINT(0xd1, 0xf),    /* MEM_LOAD_UOPS_RETIRED.* */
          INTEL_EVENT_CONSTRAINT(0xd2, 0xf),    /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
@@@ -556,10 -430,8 +556,10 @@@ struct event_constraint *intel_pebs_con
  
        if (x86_pmu.pebs_constraints) {
                for_each_event_constraint(c, x86_pmu.pebs_constraints) {
 -                      if ((event->hw.config & c->cmask) == c->code)
 +                      if ((event->hw.config & c->cmask) == c->code) {
 +                              event->hw.flags |= c->flags;
                                return c;
 +                      }
                }
        }
  
@@@ -574,11 -446,6 +574,11 @@@ void intel_pmu_pebs_enable(struct perf_
        hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
  
        cpuc->pebs_enabled |= 1ULL << hwc->idx;
 +
 +      if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT)
 +              cpuc->pebs_enabled |= 1ULL << (hwc->idx + 32);
 +      else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
 +              cpuc->pebs_enabled |= 1ULL << 63;
  }
  
  void intel_pmu_pebs_disable(struct perf_event *event)
@@@ -691,51 -558,20 +691,51 @@@ static void __intel_pmu_pebs_event(stru
                                   struct pt_regs *iregs, void *__pebs)
  {
        /*
 -       * We cast to pebs_record_core since that is a subset of
 -       * both formats and we don't use the other fields in this
 -       * routine.
 +       * We cast to pebs_record_nhm to get the load latency data
 +       * if extra_reg MSR_PEBS_LD_LAT_THRESHOLD used
         */
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 -      struct pebs_record_core *pebs = __pebs;
 +      struct pebs_record_nhm *pebs = __pebs;
        struct perf_sample_data data;
        struct pt_regs regs;
 +      u64 sample_type;
 +      int fll, fst;
  
        if (!intel_pmu_save_and_restart(event))
                return;
  
 +      fll = event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT;
 +      fst = event->hw.flags & PERF_X86_EVENT_PEBS_ST;
 +
        perf_sample_data_init(&data, 0, event->hw.last_period);
  
 +      data.period = event->hw.last_period;
 +      sample_type = event->attr.sample_type;
 +
 +      /*
 +       * if PEBS-LL or PreciseStore
 +       */
 +      if (fll || fst) {
 +              if (sample_type & PERF_SAMPLE_ADDR)
 +                      data.addr = pebs->dla;
 +
 +              /*
 +               * Use latency for weight (only avail with PEBS-LL)
 +               */
 +              if (fll && (sample_type & PERF_SAMPLE_WEIGHT))
 +                      data.weight = pebs->lat;
 +
 +              /*
 +               * data.data_src encodes the data source
 +               */
 +              if (sample_type & PERF_SAMPLE_DATA_SRC) {
 +                      if (fll)
 +                              data.data_src.val = load_latency_data(pebs->dse);
 +                      else
 +                              data.data_src.val = precise_store_data(pebs->dse);
 +              }
 +      }
 +
        /*
         * We use the interrupt regs as a base because the PEBS record
         * does not contain a full regs set, specifically it seems to
@@@ -893,3 -729,13 +893,13 @@@ void intel_ds_init(void
                }
        }
  }
+ void perf_restore_debug_store(void)
+ {
+       struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
+       if (!x86_pmu.bts && !x86_pmu.pebs)
+               return;
+       wrmsrl(MSR_IA32_DS_AREA, (unsigned long)ds);
+ }
index 42a6daaf4e0af88bb78121742989503a46cbd2b2,1d795df6f4cfdb53575efe2fd756015c0ad363de..e0373d26c24454a313fa47bb96d5211458db1c2d
@@@ -21,6 -21,7 +21,6 @@@
   */
  
  #ifdef CONFIG_PERF_EVENTS
 -# include <linux/cgroup.h>
  # include <asm/perf_event.h>
  # include <asm/local64.h>
  #endif
@@@ -127,7 -128,6 +127,7 @@@ struct hw_perf_event 
                        int             event_base_rdpmc;
                        int             idx;
                        int             last_cpu;
 +                      int             flags;
  
                        struct hw_perf_event_extra extra_reg;
                        struct hw_perf_event_extra branch_reg;
@@@ -299,7 -299,22 +299,7 @@@ struct swevent_hlist 
  #define PERF_ATTACH_GROUP     0x02
  #define PERF_ATTACH_TASK      0x04
  
 -#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 *info; /* timing info, one per cpu */
 -};
 -#endif
 -
 +struct perf_cgroup;
  struct ring_buffer;
  
  /**
@@@ -568,13 -583,11 +568,13 @@@ struct perf_sample_data 
                u32     reserved;
        }                               cpu_entry;
        u64                             period;
 +      union  perf_mem_data_src        data_src;
        struct perf_callchain_entry     *callchain;
        struct perf_raw_record          *raw;
        struct perf_branch_stack        *br_stack;
        struct perf_regs_user           regs_user;
        u64                             stack_user_size;
 +      u64                             weight;
  };
  
  static inline void perf_sample_data_init(struct perf_sample_data *data,
        data->regs_user.abi = PERF_SAMPLE_REGS_ABI_NONE;
        data->regs_user.regs = NULL;
        data->stack_user_size = 0;
 +      data->weight = 0;
 +      data->data_src.val = 0;
  }
  
  extern void perf_output_sample(struct perf_output_handle *handle,
@@@ -788,6 -799,12 +788,12 @@@ static inline int __perf_event_disable(
  static inline void perf_event_task_tick(void)                         { }
  #endif
  
+ #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
+ extern void perf_restore_debug_store(void);
+ #else
+ static inline void perf_restore_debug_store(void)                     { }
+ #endif
  #define perf_output_put(handle, x) perf_output_copy((handle), &(x), sizeof(x))
  
  /*
@@@ -814,7 -831,6 +820,7 @@@ do {                                                                       
  struct perf_pmu_events_attr {
        struct device_attribute attr;
        u64 id;
 +      const char *event_str;
  };
  
  #define PMU_EVENT_ATTR(_name, _var, _id, _show)                               \