powerpc/perf: Export memory hierarchy info to user space
The LDST field and DATA_SRC in SIER identifies the memory hierarchy level (eg: L1, L2 etc), from which a data-cache miss for a marked instruction was satisfied. Use the 'perf_mem_data_src' object to export this hierarchy level to user space. Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
8c5073db0e
commit
79e96f8f93
@ -38,6 +38,8 @@ struct power_pmu {
|
||||
unsigned long *valp);
|
||||
int (*get_alternatives)(u64 event_id, unsigned int flags,
|
||||
u64 alt[]);
|
||||
void (*get_mem_data_src)(union perf_mem_data_src *dsrc,
|
||||
u32 flags, struct pt_regs *regs);
|
||||
u64 (*bhrb_filter_map)(u64 branch_sample_type);
|
||||
void (*config_bhrb)(u64 pmu_bhrb_filter);
|
||||
void (*disable_pmc)(unsigned int pmc, unsigned long mmcr[]);
|
||||
|
@ -2049,6 +2049,10 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
|
||||
data.br_stack = &cpuhw->bhrb_stack;
|
||||
}
|
||||
|
||||
if (event->attr.sample_type & PERF_SAMPLE_DATA_SRC &&
|
||||
ppmu->get_mem_data_src)
|
||||
ppmu->get_mem_data_src(&data.data_src, ppmu->flags, regs);
|
||||
|
||||
if (perf_event_overflow(event, &data, regs))
|
||||
power_pmu_stop(event, 0);
|
||||
}
|
||||
|
@ -148,6 +148,80 @@ static bool is_thresh_cmp_valid(u64 event)
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline u64 isa207_find_source(u64 idx, u32 sub_idx)
|
||||
{
|
||||
u64 ret = PERF_MEM_NA;
|
||||
|
||||
switch(idx) {
|
||||
case 0:
|
||||
/* Nothing to do */
|
||||
break;
|
||||
case 1:
|
||||
ret = PH(LVL, L1);
|
||||
break;
|
||||
case 2:
|
||||
ret = PH(LVL, L2);
|
||||
break;
|
||||
case 3:
|
||||
ret = PH(LVL, L3);
|
||||
break;
|
||||
case 4:
|
||||
if (sub_idx <= 1)
|
||||
ret = PH(LVL, LOC_RAM);
|
||||
else if (sub_idx > 1 && sub_idx <= 2)
|
||||
ret = PH(LVL, REM_RAM1);
|
||||
else
|
||||
ret = PH(LVL, REM_RAM2);
|
||||
ret |= P(SNOOP, HIT);
|
||||
break;
|
||||
case 5:
|
||||
ret = PH(LVL, REM_CCE1);
|
||||
if ((sub_idx == 0) || (sub_idx == 2) || (sub_idx == 4))
|
||||
ret |= P(SNOOP, HIT);
|
||||
else if ((sub_idx == 1) || (sub_idx == 3) || (sub_idx == 5))
|
||||
ret |= P(SNOOP, HITM);
|
||||
break;
|
||||
case 6:
|
||||
ret = PH(LVL, REM_CCE2);
|
||||
if ((sub_idx == 0) || (sub_idx == 2))
|
||||
ret |= P(SNOOP, HIT);
|
||||
else if ((sub_idx == 1) || (sub_idx == 3))
|
||||
ret |= P(SNOOP, HITM);
|
||||
break;
|
||||
case 7:
|
||||
ret = PM(LVL, L1);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void isa207_get_mem_data_src(union perf_mem_data_src *dsrc, u32 flags,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
u64 idx;
|
||||
u32 sub_idx;
|
||||
u64 sier;
|
||||
u64 val;
|
||||
|
||||
/* Skip if no SIER support */
|
||||
if (!(flags & PPMU_HAS_SIER)) {
|
||||
dsrc->val = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
sier = mfspr(SPRN_SIER);
|
||||
val = (sier & ISA207_SIER_TYPE_MASK) >> ISA207_SIER_TYPE_SHIFT;
|
||||
if (val == 1 || val == 2) {
|
||||
idx = (sier & ISA207_SIER_LDST_MASK) >> ISA207_SIER_LDST_SHIFT;
|
||||
sub_idx = (sier & ISA207_SIER_DATA_SRC_MASK) >> ISA207_SIER_DATA_SRC_SHIFT;
|
||||
|
||||
dsrc->val = isa207_find_source(idx, sub_idx);
|
||||
dsrc->val |= (val == 1) ? P(OP, LOAD) : P(OP, STORE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp)
|
||||
{
|
||||
unsigned int unit, pmc, cache, ebb;
|
||||
|
@ -260,6 +260,19 @@
|
||||
#define MAX_ALT 2
|
||||
#define MAX_PMU_COUNTERS 6
|
||||
|
||||
#define ISA207_SIER_TYPE_SHIFT 15
|
||||
#define ISA207_SIER_TYPE_MASK (0x7ull << ISA207_SIER_TYPE_SHIFT)
|
||||
|
||||
#define ISA207_SIER_LDST_SHIFT 1
|
||||
#define ISA207_SIER_LDST_MASK (0x7ull << ISA207_SIER_LDST_SHIFT)
|
||||
|
||||
#define ISA207_SIER_DATA_SRC_SHIFT 53
|
||||
#define ISA207_SIER_DATA_SRC_MASK (0x7ull << ISA207_SIER_DATA_SRC_SHIFT)
|
||||
|
||||
#define P(a, b) PERF_MEM_S(a, b)
|
||||
#define PH(a, b) (P(LVL, HIT) | P(a, b))
|
||||
#define PM(a, b) (P(LVL, MISS) | P(a, b))
|
||||
|
||||
int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp);
|
||||
int isa207_compute_mmcr(u64 event[], int n_ev,
|
||||
unsigned int hwc[], unsigned long mmcr[],
|
||||
@ -267,6 +280,7 @@ int isa207_compute_mmcr(u64 event[], int n_ev,
|
||||
void isa207_disable_pmc(unsigned int pmc, unsigned long mmcr[]);
|
||||
int isa207_get_alternatives(u64 event, u64 alt[],
|
||||
const unsigned int ev_alt[][MAX_ALT], int size);
|
||||
|
||||
void isa207_get_mem_data_src(union perf_mem_data_src *dsrc, u32 flags,
|
||||
struct pt_regs *regs);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user