Merge tag 'arm64-perf' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm[64] perf updates from Will Deacon:
 "In the past, I have funnelled perf updates through the respective
  architecture trees, but now that the arm/arm64 perf driver has been
  largely consolidated under drivers/perf/, it makes more sense to send
  a separate pull, particularly as I'm listed as maintainer for all the
  files involved.  I offered the branch to arm-soc, but Arnd suggested
  that I just send it to you directly.

  So, here is the arm/arm64 perf queue for 4.5.  The main features are
  described below, but the most useful change is from Drew, which
  advertises our architected event mapping in sysfs so that the perf
  tool is a lot more user friendly and no longer requires the use of
  magic hex constants for profiling common events.

   - Support for the CPU PMU in Cortex-A72

   - Add sysfs entries to describe the architected events and their
     mappings for PMUv{1-3}"

* tag 'arm64-perf' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  arm64: perf: add support for Cortex-A72
  arm64: perf: add format entry to describe event -> config mapping
  ARM: perf: add format entry to describe event -> config mapping
  arm64: kernel: enforce pmuserenr_el0 initialization and restore
  arm64: perf: Correct Cortex-A53/A57 compatible values
  arm64: perf: Add event descriptions
  arm64: perf: Convert event enums to #defines
  arm: perf: Add event descriptions
  arm: perf: Convert event enums to #defines
  drivers/perf: kill armpmu_register
This commit is contained in:
Linus Torvalds
2016-01-12 12:29:25 -08:00
6 changed files with 435 additions and 163 deletions

View File

@@ -29,60 +29,74 @@
* ARMv8 PMUv3 Performance Events handling code.
* Common event types.
*/
enum armv8_pmuv3_perf_types {
/* Required events. */
ARMV8_PMUV3_PERFCTR_PMNC_SW_INCR = 0x00,
ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL = 0x03,
ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS = 0x04,
ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES = 0x11,
ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED = 0x12,
/* At least one of the following is required. */
ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED = 0x08,
ARMV8_PMUV3_PERFCTR_OP_SPEC = 0x1B,
/* Required events. */
#define ARMV8_PMUV3_PERFCTR_PMNC_SW_INCR 0x00
#define ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL 0x03
#define ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS 0x04
#define ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED 0x10
#define ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES 0x11
#define ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED 0x12
/* Common architectural events. */
ARMV8_PMUV3_PERFCTR_MEM_READ = 0x06,
ARMV8_PMUV3_PERFCTR_MEM_WRITE = 0x07,
ARMV8_PMUV3_PERFCTR_EXC_TAKEN = 0x09,
ARMV8_PMUV3_PERFCTR_EXC_EXECUTED = 0x0A,
ARMV8_PMUV3_PERFCTR_CID_WRITE = 0x0B,
ARMV8_PMUV3_PERFCTR_PC_WRITE = 0x0C,
ARMV8_PMUV3_PERFCTR_PC_IMM_BRANCH = 0x0D,
ARMV8_PMUV3_PERFCTR_PC_PROC_RETURN = 0x0E,
ARMV8_PMUV3_PERFCTR_MEM_UNALIGNED_ACCESS = 0x0F,
ARMV8_PMUV3_PERFCTR_TTBR_WRITE = 0x1C,
/* At least one of the following is required. */
#define ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED 0x08
#define ARMV8_PMUV3_PERFCTR_OP_SPEC 0x1B
/* Common microarchitectural events. */
ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL = 0x01,
ARMV8_PMUV3_PERFCTR_ITLB_REFILL = 0x02,
ARMV8_PMUV3_PERFCTR_DTLB_REFILL = 0x05,
ARMV8_PMUV3_PERFCTR_MEM_ACCESS = 0x13,
ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS = 0x14,
ARMV8_PMUV3_PERFCTR_L1_DCACHE_WB = 0x15,
ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS = 0x16,
ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL = 0x17,
ARMV8_PMUV3_PERFCTR_L2_CACHE_WB = 0x18,
ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19,
ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A,
ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D,
};
/* Common architectural events. */
#define ARMV8_PMUV3_PERFCTR_MEM_READ 0x06
#define ARMV8_PMUV3_PERFCTR_MEM_WRITE 0x07
#define ARMV8_PMUV3_PERFCTR_EXC_TAKEN 0x09
#define ARMV8_PMUV3_PERFCTR_EXC_EXECUTED 0x0A
#define ARMV8_PMUV3_PERFCTR_CID_WRITE 0x0B
#define ARMV8_PMUV3_PERFCTR_PC_WRITE 0x0C
#define ARMV8_PMUV3_PERFCTR_PC_IMM_BRANCH 0x0D
#define ARMV8_PMUV3_PERFCTR_PC_PROC_RETURN 0x0E
#define ARMV8_PMUV3_PERFCTR_MEM_UNALIGNED_ACCESS 0x0F
#define ARMV8_PMUV3_PERFCTR_TTBR_WRITE 0x1C
#define ARMV8_PMUV3_PERFCTR_CHAIN 0x1E
#define ARMV8_PMUV3_PERFCTR_BR_RETIRED 0x21
/* Common microarchitectural events. */
#define ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL 0x01
#define ARMV8_PMUV3_PERFCTR_ITLB_REFILL 0x02
#define ARMV8_PMUV3_PERFCTR_DTLB_REFILL 0x05
#define ARMV8_PMUV3_PERFCTR_MEM_ACCESS 0x13
#define ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS 0x14
#define ARMV8_PMUV3_PERFCTR_L1_DCACHE_WB 0x15
#define ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS 0x16
#define ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL 0x17
#define ARMV8_PMUV3_PERFCTR_L2_CACHE_WB 0x18
#define ARMV8_PMUV3_PERFCTR_BUS_ACCESS 0x19
#define ARMV8_PMUV3_PERFCTR_MEM_ERROR 0x1A
#define ARMV8_PMUV3_PERFCTR_BUS_CYCLES 0x1D
#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_ALLOCATE 0x1F
#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_ALLOCATE 0x20
#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED_RETIRED 0x22
#define ARMV8_PMUV3_PERFCTR_STALL_FRONTEND 0x23
#define ARMV8_PMUV3_PERFCTR_STALL_BACKEND 0x24
#define ARMV8_PMUV3_PERFCTR_L1D_TLB 0x25
#define ARMV8_PMUV3_PERFCTR_L1I_TLB 0x26
#define ARMV8_PMUV3_PERFCTR_L2I_CACHE 0x27
#define ARMV8_PMUV3_PERFCTR_L2I_CACHE_REFILL 0x28
#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_ALLOCATE 0x29
#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_REFILL 0x2A
#define ARMV8_PMUV3_PERFCTR_L3D_CACHE 0x2B
#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_WB 0x2C
#define ARMV8_PMUV3_PERFCTR_L2D_TLB_REFILL 0x2D
#define ARMV8_PMUV3_PERFCTR_L21_TLB_REFILL 0x2E
#define ARMV8_PMUV3_PERFCTR_L2D_TLB 0x2F
#define ARMV8_PMUV3_PERFCTR_L21_TLB 0x30
/* ARMv8 Cortex-A53 specific event types. */
enum armv8_a53_pmu_perf_types {
ARMV8_A53_PERFCTR_PREFETCH_LINEFILL = 0xC2,
};
#define ARMV8_A53_PERFCTR_PREFETCH_LINEFILL 0xC2
/* ARMv8 Cortex-A57 specific event types. */
enum armv8_a57_perf_types {
ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_LD = 0x40,
ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_ST = 0x41,
ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_LD = 0x42,
ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_ST = 0x43,
ARMV8_A57_PERFCTR_DTLB_REFILL_LD = 0x4c,
ARMV8_A57_PERFCTR_DTLB_REFILL_ST = 0x4d,
};
/* ARMv8 Cortex-A57 and Cortex-A72 specific event types. */
#define ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_LD 0x40
#define ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_ST 0x41
#define ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_LD 0x42
#define ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_ST 0x43
#define ARMV8_A57_PERFCTR_DTLB_REFILL_LD 0x4c
#define ARMV8_A57_PERFCTR_DTLB_REFILL_ST 0x4d
/* PMUv3 HW events mapping. */
static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
@@ -106,6 +120,7 @@ static const unsigned armv8_a53_perf_map[PERF_COUNT_HW_MAX] = {
[PERF_COUNT_HW_BUS_CYCLES] = ARMV8_PMUV3_PERFCTR_BUS_CYCLES,
};
/* ARM Cortex-A57 and Cortex-A72 events mapping. */
static const unsigned armv8_a57_perf_map[PERF_COUNT_HW_MAX] = {
PERF_MAP_ALL_UNSUPPORTED,
[PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES,
@@ -178,6 +193,137 @@ static const unsigned armv8_a57_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
};
#define ARMV8_EVENT_ATTR_RESOLVE(m) #m
#define ARMV8_EVENT_ATTR(name, config) \
PMU_EVENT_ATTR_STRING(name, armv8_event_attr_##name, \
"event=" ARMV8_EVENT_ATTR_RESOLVE(config))
ARMV8_EVENT_ATTR(sw_incr, ARMV8_PMUV3_PERFCTR_PMNC_SW_INCR);
ARMV8_EVENT_ATTR(l1i_cache_refill, ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL);
ARMV8_EVENT_ATTR(l1i_tlb_refill, ARMV8_PMUV3_PERFCTR_ITLB_REFILL);
ARMV8_EVENT_ATTR(l1d_cache_refill, ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL);
ARMV8_EVENT_ATTR(l1d_cache, ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS);
ARMV8_EVENT_ATTR(l1d_tlb_refill, ARMV8_PMUV3_PERFCTR_DTLB_REFILL);
ARMV8_EVENT_ATTR(ld_retired, ARMV8_PMUV3_PERFCTR_MEM_READ);
ARMV8_EVENT_ATTR(st_retired, ARMV8_PMUV3_PERFCTR_MEM_WRITE);
ARMV8_EVENT_ATTR(inst_retired, ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED);
ARMV8_EVENT_ATTR(exc_taken, ARMV8_PMUV3_PERFCTR_EXC_TAKEN);
ARMV8_EVENT_ATTR(exc_return, ARMV8_PMUV3_PERFCTR_EXC_EXECUTED);
ARMV8_EVENT_ATTR(cid_write_retired, ARMV8_PMUV3_PERFCTR_CID_WRITE);
ARMV8_EVENT_ATTR(pc_write_retired, ARMV8_PMUV3_PERFCTR_PC_WRITE);
ARMV8_EVENT_ATTR(br_immed_retired, ARMV8_PMUV3_PERFCTR_PC_IMM_BRANCH);
ARMV8_EVENT_ATTR(br_return_retired, ARMV8_PMUV3_PERFCTR_PC_PROC_RETURN);
ARMV8_EVENT_ATTR(unaligned_ldst_retired, ARMV8_PMUV3_PERFCTR_MEM_UNALIGNED_ACCESS);
ARMV8_EVENT_ATTR(br_mis_pred, ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED);
ARMV8_EVENT_ATTR(cpu_cycles, ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES);
ARMV8_EVENT_ATTR(br_pred, ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED);
ARMV8_EVENT_ATTR(mem_access, ARMV8_PMUV3_PERFCTR_MEM_ACCESS);
ARMV8_EVENT_ATTR(l1i_cache, ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS);
ARMV8_EVENT_ATTR(l1d_cache_wb, ARMV8_PMUV3_PERFCTR_L1_DCACHE_WB);
ARMV8_EVENT_ATTR(l2d_cache, ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS);
ARMV8_EVENT_ATTR(l2d_cache_refill, ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL);
ARMV8_EVENT_ATTR(l2d_cache_wb, ARMV8_PMUV3_PERFCTR_L2_CACHE_WB);
ARMV8_EVENT_ATTR(bus_access, ARMV8_PMUV3_PERFCTR_BUS_ACCESS);
ARMV8_EVENT_ATTR(memory_error, ARMV8_PMUV3_PERFCTR_MEM_ERROR);
ARMV8_EVENT_ATTR(inst_spec, ARMV8_PMUV3_PERFCTR_OP_SPEC);
ARMV8_EVENT_ATTR(ttbr_write_retired, ARMV8_PMUV3_PERFCTR_TTBR_WRITE);
ARMV8_EVENT_ATTR(bus_cycles, ARMV8_PMUV3_PERFCTR_BUS_CYCLES);
ARMV8_EVENT_ATTR(chain, ARMV8_PMUV3_PERFCTR_CHAIN);
ARMV8_EVENT_ATTR(l1d_cache_allocate, ARMV8_PMUV3_PERFCTR_L1D_CACHE_ALLOCATE);
ARMV8_EVENT_ATTR(l2d_cache_allocate, ARMV8_PMUV3_PERFCTR_L2D_CACHE_ALLOCATE);
ARMV8_EVENT_ATTR(br_retired, ARMV8_PMUV3_PERFCTR_BR_RETIRED);
ARMV8_EVENT_ATTR(br_mis_pred_retired, ARMV8_PMUV3_PERFCTR_BR_MIS_PRED_RETIRED);
ARMV8_EVENT_ATTR(stall_frontend, ARMV8_PMUV3_PERFCTR_STALL_FRONTEND);
ARMV8_EVENT_ATTR(stall_backend, ARMV8_PMUV3_PERFCTR_STALL_BACKEND);
ARMV8_EVENT_ATTR(l1d_tlb, ARMV8_PMUV3_PERFCTR_L1D_TLB);
ARMV8_EVENT_ATTR(l1i_tlb, ARMV8_PMUV3_PERFCTR_L1I_TLB);
ARMV8_EVENT_ATTR(l2i_cache, ARMV8_PMUV3_PERFCTR_L2I_CACHE);
ARMV8_EVENT_ATTR(l2i_cache_refill, ARMV8_PMUV3_PERFCTR_L2I_CACHE_REFILL);
ARMV8_EVENT_ATTR(l3d_cache_allocate, ARMV8_PMUV3_PERFCTR_L3D_CACHE_ALLOCATE);
ARMV8_EVENT_ATTR(l3d_cache_refill, ARMV8_PMUV3_PERFCTR_L3D_CACHE_REFILL);
ARMV8_EVENT_ATTR(l3d_cache, ARMV8_PMUV3_PERFCTR_L3D_CACHE);
ARMV8_EVENT_ATTR(l3d_cache_wb, ARMV8_PMUV3_PERFCTR_L3D_CACHE_WB);
ARMV8_EVENT_ATTR(l2d_tlb_refill, ARMV8_PMUV3_PERFCTR_L2D_TLB_REFILL);
ARMV8_EVENT_ATTR(l21_tlb_refill, ARMV8_PMUV3_PERFCTR_L21_TLB_REFILL);
ARMV8_EVENT_ATTR(l2d_tlb, ARMV8_PMUV3_PERFCTR_L2D_TLB);
ARMV8_EVENT_ATTR(l21_tlb, ARMV8_PMUV3_PERFCTR_L21_TLB);
static struct attribute *armv8_pmuv3_event_attrs[] = {
&armv8_event_attr_sw_incr.attr.attr,
&armv8_event_attr_l1i_cache_refill.attr.attr,
&armv8_event_attr_l1i_tlb_refill.attr.attr,
&armv8_event_attr_l1d_cache_refill.attr.attr,
&armv8_event_attr_l1d_cache.attr.attr,
&armv8_event_attr_l1d_tlb_refill.attr.attr,
&armv8_event_attr_ld_retired.attr.attr,
&armv8_event_attr_st_retired.attr.attr,
&armv8_event_attr_inst_retired.attr.attr,
&armv8_event_attr_exc_taken.attr.attr,
&armv8_event_attr_exc_return.attr.attr,
&armv8_event_attr_cid_write_retired.attr.attr,
&armv8_event_attr_pc_write_retired.attr.attr,
&armv8_event_attr_br_immed_retired.attr.attr,
&armv8_event_attr_br_return_retired.attr.attr,
&armv8_event_attr_unaligned_ldst_retired.attr.attr,
&armv8_event_attr_br_mis_pred.attr.attr,
&armv8_event_attr_cpu_cycles.attr.attr,
&armv8_event_attr_br_pred.attr.attr,
&armv8_event_attr_mem_access.attr.attr,
&armv8_event_attr_l1i_cache.attr.attr,
&armv8_event_attr_l1d_cache_wb.attr.attr,
&armv8_event_attr_l2d_cache.attr.attr,
&armv8_event_attr_l2d_cache_refill.attr.attr,
&armv8_event_attr_l2d_cache_wb.attr.attr,
&armv8_event_attr_bus_access.attr.attr,
&armv8_event_attr_memory_error.attr.attr,
&armv8_event_attr_inst_spec.attr.attr,
&armv8_event_attr_ttbr_write_retired.attr.attr,
&armv8_event_attr_bus_cycles.attr.attr,
&armv8_event_attr_chain.attr.attr,
&armv8_event_attr_l1d_cache_allocate.attr.attr,
&armv8_event_attr_l2d_cache_allocate.attr.attr,
&armv8_event_attr_br_retired.attr.attr,
&armv8_event_attr_br_mis_pred_retired.attr.attr,
&armv8_event_attr_stall_frontend.attr.attr,
&armv8_event_attr_stall_backend.attr.attr,
&armv8_event_attr_l1d_tlb.attr.attr,
&armv8_event_attr_l1i_tlb.attr.attr,
&armv8_event_attr_l2i_cache.attr.attr,
&armv8_event_attr_l2i_cache_refill.attr.attr,
&armv8_event_attr_l3d_cache_allocate.attr.attr,
&armv8_event_attr_l3d_cache_refill.attr.attr,
&armv8_event_attr_l3d_cache.attr.attr,
&armv8_event_attr_l3d_cache_wb.attr.attr,
&armv8_event_attr_l2d_tlb_refill.attr.attr,
&armv8_event_attr_l21_tlb_refill.attr.attr,
&armv8_event_attr_l2d_tlb.attr.attr,
&armv8_event_attr_l21_tlb.attr.attr,
NULL,
};
static struct attribute_group armv8_pmuv3_events_attr_group = {
.name = "events",
.attrs = armv8_pmuv3_event_attrs,
};
PMU_FORMAT_ATTR(event, "config:0-9");
static struct attribute *armv8_pmuv3_format_attrs[] = {
&format_attr_event.attr,
NULL,
};
static struct attribute_group armv8_pmuv3_format_attr_group = {
.name = "format",
.attrs = armv8_pmuv3_format_attrs,
};
static const struct attribute_group *armv8_pmuv3_attr_groups[] = {
&armv8_pmuv3_events_attr_group,
&armv8_pmuv3_format_attr_group,
NULL,
};
/*
* Perf Events' indices
@@ -574,9 +720,6 @@ static void armv8pmu_reset(void *info)
/* Initialize & Reset PMNC: C and P bits. */
armv8pmu_pmcr_write(ARMV8_PMCR_P | ARMV8_PMCR_C);
/* Disable access from userspace. */
asm volatile("msr pmuserenr_el0, %0" :: "r" (0));
}
static int armv8_pmuv3_map_event(struct perf_event *event)
@@ -646,6 +789,7 @@ static int armv8_a53_pmu_init(struct arm_pmu *cpu_pmu)
armv8_pmu_init(cpu_pmu);
cpu_pmu->name = "armv8_cortex_a53";
cpu_pmu->map_event = armv8_a53_map_event;
cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
return armv8pmu_probe_num_events(cpu_pmu);
}
@@ -654,6 +798,16 @@ static int armv8_a57_pmu_init(struct arm_pmu *cpu_pmu)
armv8_pmu_init(cpu_pmu);
cpu_pmu->name = "armv8_cortex_a57";
cpu_pmu->map_event = armv8_a57_map_event;
cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
return armv8pmu_probe_num_events(cpu_pmu);
}
static int armv8_a72_pmu_init(struct arm_pmu *cpu_pmu)
{
armv8_pmu_init(cpu_pmu);
cpu_pmu->name = "armv8_cortex_a72";
cpu_pmu->map_event = armv8_a57_map_event;
cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups;
return armv8pmu_probe_num_events(cpu_pmu);
}
@@ -661,6 +815,7 @@ static const struct of_device_id armv8_pmu_of_device_ids[] = {
{.compatible = "arm,armv8-pmuv3", .data = armv8_pmuv3_init},
{.compatible = "arm,cortex-a53-pmu", .data = armv8_a53_pmu_init},
{.compatible = "arm,cortex-a57-pmu", .data = armv8_a57_pmu_init},
{.compatible = "arm,cortex-a72-pmu", .data = armv8_a72_pmu_init},
{},
};