Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Linux: Kernel

[PATCH 4/7] perf/x86-ibs: Add support for IBS pseudo events

 

 

Linux kernel RSS feed   Index | Next | Previous | View Threaded


robert.richter at amd

May 2, 2012, 11:26 AM

Post #1 of 13 (279 views)
Permalink
[PATCH 4/7] perf/x86-ibs: Add support for IBS pseudo events

This patch implements support for IBS pseudo events. Pseudo events are
derived from an IBS sample and determined through a combination of one
or more IBS event flags or values. See here for a full description:

Software Optimization Guide for AMD Family 15h Processors
Appendix F Guide to Instruction-Based Sampling on AMD Family 15h Processors
Advanced Micro Devices, Inc.
Publication No. 47414, Revision 3.06
January 2012
http://support.amd.com/us/Processor_TechDocs/47414_15h_sw_opt_guide.pdf

The list of supported events is provided by perf-list. A pseudo event
can be set up like this:

# perf record -a -e ibs_op:MISPREDICTED_BRANCH ...

The filter rules for IBS samples depending on a pseudo event are also
described in the document above. The filter is setup in the perf tool
pmu handler and passed to the kernel via config1/config2 attr values.
The interface is extendable to pass the pseudo events directly to the
kernel.

There are some pseudo events capable to count latencies or other
values. Counting values of such events is not yet supported.

This patch includes kernel and userland changes.

Signed-off-by: Robert Richter <robert.richter [at] amd>
---
arch/x86/kernel/cpu/perf_event_amd_ibs.c | 83 ++++++-
tools/perf/util/pmu-ibs.c | 433 +++++++++++++++++++++++++-----
2 files changed, 445 insertions(+), 71 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
index 03743ad..1675479 100644
--- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c
+++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
@@ -478,6 +478,81 @@ static struct perf_ibs perf_ibs_op = {
.get_count = get_ibs_op_count,
};

+enum ibs_filter_type {
+ IBS_NO_FILTER = 0,
+ IBS_MATCH_FILTER = 1,
+ IBS_ANY_SET_FILTER = 2,
+ IBS_PSEUDO_EVENT = 0x0F,
+};
+
+struct ibs_filter {
+ struct {
+ u16 idx : 8;
+ u16 reserved : 4;
+ u16 type : 4;
+ };
+ union {
+ struct {
+ u8 mask;
+ u8 match;
+ };
+ u16 any;
+ };
+};
+
+static bool
+__perf_ibs_sample_matches(struct ibs_filter *filter, void *data, int size)
+{
+ int left = size;
+
+ switch (filter->type) {
+ case IBS_MATCH_FILTER:
+ left -= sizeof(u8);
+ break;
+ case IBS_ANY_SET_FILTER:
+ left -= sizeof(u16);
+ break;
+ default:
+ return false;
+ }
+
+ left -= filter->idx;
+ if (left < 0)
+ return false;
+
+ switch (filter->type) {
+ case IBS_MATCH_FILTER:
+ return ((*(u8*)(data + filter->idx)) & filter->mask) == filter->match;
+ case IBS_ANY_SET_FILTER:
+ return (*(u16*)(data + filter->idx)) & filter->any;
+ };
+
+ return false;
+}
+
+static bool perf_ibs_sample_matches(struct perf_event *event,
+ struct perf_ibs_data *data)
+{
+ int i;
+ union {
+ struct ibs_filter filter[4];
+ u64 config[2];
+ } f;
+ struct ibs_filter *filter = f.filter;
+
+ f.config[0] = event->attr.config1;
+ f.config[1] = event->attr.config2;
+
+ for (i = 0; i < 4; i++, filter++) {
+ if (filter->type == IBS_NO_FILTER)
+ break;
+ if (!__perf_ibs_sample_matches(filter, data->regs, data->size))
+ return false;
+ }
+
+ return true;
+}
+
static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
{
struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
@@ -487,7 +562,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
struct perf_raw_record raw;
struct pt_regs regs;
struct perf_ibs_data ibs_data;
- int offset, size, check_rip, offset_max, throttle = 0;
+ int offset, size, check_rip, filter, offset_max, throttle = 0;
unsigned int msr;
u64 *buf, *config, period;

@@ -517,7 +592,8 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
size = 1;
offset = 1;
check_rip = (perf_ibs == &perf_ibs_op && (ibs_caps & IBS_CAPS_RIPINVALIDCHK));
- if (event->attr.sample_type & PERF_SAMPLE_RAW)
+ filter = (event->attr.config1 != 0);
+ if (filter || (event->attr.sample_type & PERF_SAMPLE_RAW))
offset_max = perf_ibs->offset_max;
else if (check_rip)
offset_max = 2;
@@ -532,6 +608,9 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
} while (offset < offset_max);
ibs_data.size = sizeof(u64) * size;

+ if (filter && !perf_ibs_sample_matches(event, &ibs_data))
+ goto out;
+
regs = *iregs;
if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) {
regs.flags &= ~PERF_EFLAGS_EXACT;
diff --git a/tools/perf/util/pmu-ibs.c b/tools/perf/util/pmu-ibs.c
index 07acb82..604cb8c 100644
--- a/tools/perf/util/pmu-ibs.c
+++ b/tools/perf/util/pmu-ibs.c
@@ -12,84 +12,378 @@
#include <linux/compiler.h>
#include "pmu.h"

-static const char *events[] = {
- "ibs_fetch:2M_PAGE",
- "ibs_fetch:4K_PAGE",
- "ibs_fetch:ABORTED",
- "ibs_fetch:ALL",
- "ibs_fetch:ATTEMPTED",
- "ibs_fetch:COMPLETED",
- "ibs_fetch:ICACHE_HITS",
- "ibs_fetch:ICACHE_MISSES",
- "ibs_fetch:ITLB_HITS",
- "ibs_fetch:KILLED",
- "ibs_fetch:L1_ITLB_MISSES_L2_ITLB_HITS",
- "ibs_fetch:L1_ITLB_MISSES_L2_ITLB_MISSES",
- "ibs_fetch:LATENCY",
- "ibs_op:ALL",
- "ibs_op:ALL_LOAD_STORE",
- "ibs_op:BANK_CONF_LOAD",
- "ibs_op:BANK_CONF_STORE",
- "ibs_op:BRANCH_RETIRED",
- "ibs_op:CANCELLED",
- "ibs_op:COMP_TO_RET",
- "ibs_op:DATA_CACHE_MISS",
- "ibs_op:DATA_HITS",
- "ibs_op:DC_LOAD_LAT",
- "ibs_op:DCUC_MEM_ACC",
- "ibs_op:DCWC_MEM_ACC",
- "ibs_op:FORWARD",
- "ibs_op:L1_DTLB_1G",
- "ibs_op:L1_DTLB_2M",
- "ibs_op:L1_DTLB_4K",
- "ibs_op:L1_DTLB_HITS",
- "ibs_op:L1_DTLB_MISS_L2_DTLB_HIT",
- "ibs_op:L1_L2_DTLB_MISS",
- "ibs_op:L2_DTLB_1G",
- "ibs_op:L2_DTLB_2M",
- "ibs_op:L2_DTLB_4K",
- "ibs_op:LOAD",
- "ibs_op:LOCKED",
- "ibs_op:MAB_HIT",
- "ibs_op:MISALIGNED_DATA_ACC",
- "ibs_op:MISPREDICTED_BRANCH",
- "ibs_op:MISPREDICTED_BRANCH_TAKEN",
- "ibs_op:MISPREDICTED_RETURNS",
- "ibs_op:NB_CACHE_MODIFIED",
- "ibs_op:NB_CACHE_OWNED",
- "ibs_op:NB_LOCAL_CACHE",
- "ibs_op:NB_LOCAL_CACHE_LAT",
- "ibs_op:NB_LOCAL_DRAM",
- "ibs_op:NB_LOCAL_L3",
- "ibs_op:NB_LOCAL_ONLY",
- "ibs_op:NB_LOCAL_OTHER",
- "ibs_op:NB_REMOTE_CACHE",
- "ibs_op:NB_REMOTE_CACHE_LAT",
- "ibs_op:NB_REMOTE_DRAM",
- "ibs_op:NB_REMOTE_ONLY",
- "ibs_op:NB_REMOTE_OTHER",
- "ibs_op:RESYNC",
- "ibs_op:RETURNS",
- "ibs_op:STORE",
- "ibs_op:TAG_TO_RETIRE",
- "ibs_op:TAKEN_BRANCH",
- NULL
+enum ibs_filter_type {
+ IBS_NO_FILTER = 0,
+ IBS_MATCH_FILTER = 1,
+ IBS_ANY_SET_FILTER = 2,
+ IBS_PSEUDO_EVENT = 0x0F,
+};
+
+struct ibs_filter {
+ struct {
+ __u16 idx : 8;
+ __u16 reserved : 4;
+ __u16 type : 4;
+ };
+ union {
+ struct {
+ __u8 mask;
+ __u8 match;
+ };
+ __u16 any;
+ };
+};
+
+struct ibs_event {
+ __u16 id;
+ const char *name;
+ const char *desc;
+ union {
+ __u16 pseudo_event;
+ __u64 config;
+ struct ibs_filter filter[2];
+ };
+};
+
+#define IBS_FETCH_CTL 0
+#define IBS_OP_DATA 2
+#define IBS_OP_DATA2 3
+#define IBS_OP_DATA3 4
+
+#define IBS_IDX(reg, bit) ((reg)<<3)+((bit)>>3)
+#define IBS_MASK(bit, m) (0xFF&m)
+#define IBS_MASK16(bit, m) (0xFFFF&m)
+#define IBS_FILTER_MATCH_ANY() { { 0, 0, 0 }, { .any = 0 } }
+
+#define IBS_FILTER_ANY_SET(reg, bit, m) \
+ { \
+ { \
+ .type = IBS_ANY_SET_FILTER, \
+ .idx = IBS_IDX(reg, bit), \
+ .reserved = 0, \
+ },{ \
+ .any = IBS_MASK16(bit, m), \
+ } \
+ },
+
+#define IBS_FILTER_ALL_CLEAR(reg, bit, m) \
+ { \
+ { \
+ .type = IBS_MATCH_FILTER, \
+ .idx = IBS_IDX(reg, bit), \
+ .reserved = 0, \
+ },{{ \
+ .mask = IBS_MASK(bit, m), \
+ .match = 0, \
+ }} \
+ }, \
+ { \
+ { \
+ .type = IBS_MATCH_FILTER, \
+ .idx = IBS_IDX(reg, (bit) + 8), \
+ .reserved = 0, \
+ },{{ \
+ .mask = IBS_MASK(bit, (m) >> 8), \
+ .match = 0, \
+ }} \
+ },
+
+#define IBS_FILTER_ALL_SET(reg, bit, m) \
+ { \
+ { \
+ .type = IBS_MATCH_FILTER, \
+ .idx = IBS_IDX(reg, bit), \
+ .reserved = 0, \
+ },{{ \
+ .mask = IBS_MASK(bit, m), \
+ .match = IBS_MASK(bit, m), \
+ }} \
+ },
+
+#define IBS_FILTER_MATCH(reg, bit, m, v) \
+ { \
+ { \
+ .type = IBS_MATCH_FILTER, \
+ .idx = IBS_IDX(reg, bit), \
+ .reserved = 0, \
+ },{{ \
+ .mask = IBS_MASK(bit, m), \
+ .match = IBS_MASK(bit, v), \
+ }} \
+ },
+
+#define IBS_FILTER_MATCH2(reg, reg2, bit, bit2, m, m2, v, v2) \
+ { \
+ { \
+ .type = IBS_MATCH_FILTER, \
+ .idx = IBS_IDX(reg, bit), \
+ .reserved = 0, \
+ },{{ \
+ .mask = IBS_MASK(bit, m), \
+ .match = IBS_MASK(bit, v), \
+ }} \
+ }, \
+ { \
+ { \
+ .type = IBS_MATCH_FILTER, \
+ .idx = IBS_IDX(reg2, bit2), \
+ .reserved = 0, \
+ },{{ \
+ .mask = IBS_MASK(bit2, m2), \
+ .match = IBS_MASK(bit2, v2), \
+ }} \
+ }
+
+#define IBS_EVENT(i, n, d) \
+ { \
+ .id = (i), \
+ .name = (n), \
+ .desc = (d), \
+ { .filter = { IBS_FILTER_##i } }, \
+ }
+#define IBS_FILTER(type, args...) IBS_FILTER_##type(args)
+
+/*
+ * ID Name Derivation
+ *
+ * F000 IBS fetch samples Number of all IBS fetch samples
+ * F001 IBS fetch killed Number of killed IBS fetch samples
+ * F002 IBS fetch attempted Number of non-killed IBS fetch samples
+ * F003 IBS fetch completed IbsFetchComp
+ * F004 IBS fetch aborted ~IbsFetchComp
+ * F005 IBS L1 ITLB hit ~IbsL1TlbMiss & IbsPhyAddrValid
+ * F006 IBS L1 ITLB miss, L2 ITLB hit IbsL1TlbMiss & ~IbsL2TlbMiss
+ * F007 IBS L1 ITLB miss, L2 ITLB miss IbsL1TlbMiss & IbsL2TlbMiss
+ * F008 IBS instruction cache miss IbsIcMiss
+ * F009 IBS instruction cache hit IbsFetchComp & ~IbsIcMiss
+ * F00A IBS 4K page translation IbsL1TlbPgSz=0 & IbsPhyAddrValid
+ * F00B IBS 2M page translation IbsL1TlbPgSz=1 & IbsPhyAddrValid
+ * F00C IBS 1G page translation IbsL1TlbPgSz=2 & IbsPhyAddrValid
+ * F00D Reserved
+ * F00E IBS fetch latency IbsfetchLat
+ */
+#define IBS_FILTER_0xf000 IBS_FILTER(MATCH_ANY)
+#define IBS_FILTER_0xf001 IBS_FILTER(ALL_CLEAR, IBS_FETCH_CTL, 48, 0x019c)
+#define IBS_FILTER_0xf002 IBS_FILTER(ANY_SET, IBS_FETCH_CTL, 48, 0x019c)
+#define IBS_FILTER_0xf003 IBS_FILTER(MATCH, IBS_FETCH_CTL, 48, 0x04, 0x04)
+#define IBS_FILTER_0xf004 IBS_FILTER(MATCH, IBS_FETCH_CTL, 48, 0x04, 0x00)
+#define IBS_FILTER_0xf005 IBS_FILTER(MATCH, IBS_FETCH_CTL, 48, 0x90, 0x10)
+#define IBS_FILTER_0xf006 IBS_FILTER(MATCH2, IBS_FETCH_CTL, IBS_FETCH_CTL, 56, 48, 0x01, 0x80, 0x00, 0x80)
+#define IBS_FILTER_0xf007 IBS_FILTER(MATCH2, IBS_FETCH_CTL, IBS_FETCH_CTL, 56, 48, 0x01, 0x80, 0x01, 0x80)
+#define IBS_FILTER_0xf008 IBS_FILTER(MATCH, IBS_FETCH_CTL, 48, 0x08, 0x08)
+#define IBS_FILTER_0xf009 IBS_FILTER(MATCH, IBS_FETCH_CTL, 48, 0x0C, 0x04)
+#define IBS_FILTER_0xf00a IBS_FILTER(MATCH, IBS_FETCH_CTL, 48, 0x70, 0x10)
+#define IBS_FILTER_0xf00b IBS_FILTER(MATCH, IBS_FETCH_CTL, 48, 0x70, 0x30)
+#define IBS_FILTER_0xf00c IBS_FILTER(MATCH, IBS_FETCH_CTL, 48, 0x70, 0x60)
+#if 0
+#define IBS_FILTER_0xf00e IBS_FILTER(COUNT, IBS_FETCH_CTL, 32, 0xffff)
+#endif
+
+/*
+ * ID Name Derivation
+ *
+ * F100 IBS all op samples Number of all IBS op samples
+ * F101 IBS tag to retire cycles Sum of all tag to retire cycles
+ * F102 ibs completion to retire cycles Sum of all completion to retire cycles
+ * F103 IBS branch op IbsOpBrnRet
+ * F104 IBS mispredicted branch op IbsOpBrnRet & IbsOpBrnMisp
+ * F105 IBS taken branch op IbsOpBrnRet & IbsOpBrnTaken
+ * F106 IBS mispredicted taken branch op IbsOpBrnRet & IbsOpBrnTaken & IbsOpBrnMisp
+ * F107 IBS return op IbsOpReturn
+ * F108 IBS mispredicted return op IbsOpReturn & IbsOpMispReturn
+ * F109 IBS resync op IbsOpBrnResync
+ */
+#define IBS_FILTER_0xf100 IBS_FILTER(MATCH_ANY)
+#if 0
+#define IBS_FILTER_0xf101 IBS_FILTER(COUNT, IBS_OP_DATA, 16, 0xffff)
+#define IBS_FILTER_0xf102 IBS_FILTER(COUNT, IBS_OP_DATA, 0, 0xffff)
+#endif
+#define IBS_FILTER_0xf103 IBS_FILTER(MATCH, IBS_OP_DATA, 32, 0x20, 0x20)
+#define IBS_FILTER_0xf104 IBS_FILTER(MATCH, IBS_OP_DATA, 32, 0x30, 0x30)
+#define IBS_FILTER_0xf105 IBS_FILTER(MATCH, IBS_OP_DATA, 32, 0x28, 0x28)
+#define IBS_FILTER_0xf106 IBS_FILTER(MATCH, IBS_OP_DATA, 32, 0x38, 0x38)
+#define IBS_FILTER_0xf107 IBS_FILTER(MATCH, IBS_OP_DATA, 32, 0x04, 0x04)
+#define IBS_FILTER_0xf108 IBS_FILTER(MATCH, IBS_OP_DATA, 32, 0x06, 0x06)
+#define IBS_FILTER_0xf109 IBS_FILTER(MATCH, IBS_OP_DATA, 32, 0x01, 0x01)
+
+/*
+ * ID Name Derivation
+ *
+ * F200 IBS All Load/Store Ops IbsLdOp | IbsStOp
+ * F201 IBS Load Ops IbsLdOp
+ * F202 IBS Store Ops IbsStOp
+ * F203 IBS L1 DTLB Hit ~IbsDcL1tlbMiss & IbsDcLinAddrValid
+ * F204 IBS L1 DTLB Miss L2 DTLB Hit IbsDcL1tlbMiss & ~IbsDcL2tlbMiss
+ * F205 IBS L1 DTLB Miss L2 DTLB Miss IbsDcL1tlbMiss & IbsDcL2tlbMiss
+ * F206 IBS DC Miss IbsDcMiss
+ * F207 IBS DC Hit ~IbsDcMiss
+ * F208 IBS Misaligned Access IbsDcMisAcc
+ * F209 IBS Bank Conflict On Load Op IbsDcLdBnkCon
+ * F20A Reserved
+ * F20B IBS Store to Load Forwarded IbsDcStToLdFwd
+ * F20C IBSStore to Load Forwarding Cancelled IbsDcStToLdCan
+ * F20D IBS UC memory access IbsDcUcMemAcc
+ * F20E IBS WC memory access IbsDcWcMemAcc
+ * F20F IBS locked operation IbsDcLockedOp
+ * F210 IBS MAB hit IbsDcMabHit
+ * F211 IBS L1 DTLB 4K page ~IbsDcL1tlbHit2M & ~IbsDcL1tlbHit1G &
+ * IbsDcLinAddrValid
+ * F212 IBS L1 DTLB 2M page IbsDcL1tlbHit2M & IbsDcLinAddrValid
+ * F213 IBS L1 DTLB 1G page IbsDcL1tlbHit1G & IbsDcLinAddrValid
+ * F214 Reserved
+ * F215 IBS L2 DTLB 4K page ~IbsDcL2tlbMiss & IbsDcL1tlbMiss &
+ * ~IbsDcL1tlbHit2M & lbsDcLinAddrValid
+ * F216 IBS L2 DTLB 2M page ~IbsDcL2tlbMiss & IbsDcL1tlbMiss &
+ * IbsDcL1tlbHit2M & lbsDcLinAddrValid
+ * F217 Reserved
+ * F218 Reserved
+ * F219 IBS DC miss load latency IbsDcMissLat when IbsLdOp & IbsDcMiss
+ */
+#define IBS_FILTER_0xf200 IBS_FILTER(ANY_SET, IBS_OP_DATA3, 0, 0x0003)
+#define IBS_FILTER_0xf201 IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x01, 0x01)
+#define IBS_FILTER_0xf202 IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x02, 0x02)
+#define IBS_FILTER_0xf203 IBS_FILTER(MATCH2, IBS_OP_DATA3, IBS_OP_DATA3, 16, 0, 0x02, 0x04, 0x02, 0x00)
+#define IBS_FILTER_0xf204 IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x0C, 0x08)
+#define IBS_FILTER_0xf205 IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x0C, 0x0C)
+#define IBS_FILTER_0xf206 IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x80, 0x80)
+#define IBS_FILTER_0xf207 IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x80, 0x00) IBS_FILTER(ANY_SET, IBS_OP_DATA3, 0, 0x0003)
+#define IBS_FILTER_0xf208 IBS_FILTER(MATCH, IBS_OP_DATA3, 8, 0x01, 0x01)
+#define IBS_FILTER_0xf209 IBS_FILTER(MATCH, IBS_OP_DATA3, 8, 0x02, 0x02)
+#define IBS_FILTER_0xf20b IBS_FILTER(MATCH, IBS_OP_DATA3, 8, 0x08, 0x08)
+#define IBS_FILTER_0xf20c IBS_FILTER(MATCH, IBS_OP_DATA3, 8, 0x10, 0x10)
+#define IBS_FILTER_0xf20d IBS_FILTER(MATCH, IBS_OP_DATA3, 8, 0x40, 0x40)
+#define IBS_FILTER_0xf20e IBS_FILTER(MATCH, IBS_OP_DATA3, 8, 0x20, 0x20)
+#define IBS_FILTER_0xf20f IBS_FILTER(MATCH, IBS_OP_DATA3, 8, 0x80, 0x80)
+#define IBS_FILTER_0xf210 IBS_FILTER(MATCH, IBS_OP_DATA3, 16, 0x01, 0x01)
+#define IBS_FILTER_0xf211 IBS_FILTER(MATCH2, IBS_OP_DATA3, IBS_OP_DATA3, 16, 0, 0x02, 0x30, 0x02, 0x00)
+#define IBS_FILTER_0xf212 IBS_FILTER(MATCH2, IBS_OP_DATA3, IBS_OP_DATA3, 16, 0, 0x02, 0x10, 0x02, 0x10)
+#define IBS_FILTER_0xf213 IBS_FILTER(MATCH2, IBS_OP_DATA3, IBS_OP_DATA3, 16, 0, 0x02, 0x20, 0x02, 0x20)
+#define IBS_FILTER_0xf215 IBS_FILTER(MATCH2, IBS_OP_DATA3, IBS_OP_DATA3, 16, 0, 0x02, 0x1C, 0x02, 0x04)
+#define IBS_FILTER_0xf216 IBS_FILTER(MATCH2, IBS_OP_DATA3, IBS_OP_DATA3, 16, 0, 0x02, 0x1C, 0x02, 0x14)
+#if 0
+#define IBS_FILTER_0xf219 IBS_FILTER(COUNT, IBS_OP_DATA3, 32, 0x00FFFF, 0x00FFFF)
+#endif
+
+/*
+ * ID Name Derivation
+ *
+ * F240 IBS NB local ~NbIbsReqDstProc
+ * F241 IBS NB remote NbIbsReqDstProc
+ * F242 IBS NB local L3 NbIbsReqSrc=0x1 & ~NbIbsReqDstProc
+ * F243 IBS NB local L1/L2 (intercore) NbIbsReqSrc=0x2 & ~NbIbsReqDstProc
+ * F244 IBS NB remote L1/L2/L3 cache NbIbsReqSrc=0x2 & NbIbsReqDstProc
+ * F245 IBS NB local DRAM NbIbsReqSrc=0x3 & ~NbIbsReqDstProc
+ * F246 IBS NB remote DRAM NbIbsReqSrc=0x3 & NbIbsReqDstProc
+ * F247 IBS NB local other NbIbsReqSrc=0x7 & ~NbIbsReqDstProc
+ * F248 IBS NB remote other NbIbsReqSrc=0x7 & NbIbsReqDstProc
+ * F249 IBS NB cache M state NbIbsReqSrc=0x2 & ~NbIbsReqCacheHitSt
+ * F24A IBS NB cache O state NbIbsReqSrc=0x2 & NbIbsReqCacheHitSt
+ * F24B IBS NB local latency IbsDcMissLat when ~NbIbsReqDstProc
+ * F24C IBS NB remote latency IbsDcMissLat when NbIbsReqDstProc
+ */
+#define IBS_FILTER_0xf240 IBS_FILTER(MATCH, IBS_OP_DATA2, 0, 0x10, 0x00) IBS_FILTER(ANY_SET, IBS_OP_DATA2, 0, 0x0007)
+#define IBS_FILTER_0xf241 IBS_FILTER(MATCH, IBS_OP_DATA2, 0, 0x10, 0x10) IBS_FILTER(ANY_SET, IBS_OP_DATA2, 0, 0x0007)
+#define IBS_FILTER_0xf242 IBS_FILTER(MATCH, IBS_OP_DATA2, 0, 0x17, 0x01) IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x81, 0x81)
+#define IBS_FILTER_0xf243 IBS_FILTER(MATCH, IBS_OP_DATA2, 0, 0x17, 0x02) IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x81, 0x81)
+#define IBS_FILTER_0xf244 IBS_FILTER(MATCH, IBS_OP_DATA2, 0, 0x17, 0x12) IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x81, 0x81)
+#define IBS_FILTER_0xf245 IBS_FILTER(MATCH, IBS_OP_DATA2, 0, 0x17, 0x03) IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x81, 0x81)
+#define IBS_FILTER_0xf246 IBS_FILTER(MATCH, IBS_OP_DATA2, 0, 0x17, 0x13) IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x81, 0x81)
+#define IBS_FILTER_0xf247 IBS_FILTER(MATCH, IBS_OP_DATA2, 0, 0x17, 0x07) IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x81, 0x81)
+#define IBS_FILTER_0xf248 IBS_FILTER(MATCH, IBS_OP_DATA2, 0, 0x17, 0x17) IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x81, 0x81)
+#define IBS_FILTER_0xf249 IBS_FILTER(MATCH, IBS_OP_DATA2, 0, 0x27, 0x02) IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x81, 0x81)
+#define IBS_FILTER_0xf24a IBS_FILTER(MATCH, IBS_OP_DATA2, 0, 0x27, 0x22) IBS_FILTER(MATCH, IBS_OP_DATA3, 0, 0x81, 0x81)
+
+static struct ibs_event events[] = {
+ IBS_EVENT(0xf000, "ibs_fetch:ALL", "All IBS fetch samples"),
+ IBS_EVENT(0xf001, "ibs_fetch:KILLED", "IBS fetch killed"),
+ IBS_EVENT(0xf002, "ibs_fetch:ATTEMPTED", "IBS fetch attempted"),
+ IBS_EVENT(0xf003, "ibs_fetch:COMPLETED", "IBS fetch completed"),
+ IBS_EVENT(0xf004, "ibs_fetch:ABORTED", "IBS fetch aborted"),
+ IBS_EVENT(0xf005, "ibs_fetch:ITLB_HITS", "IBS ITLB hit"),
+ IBS_EVENT(0xf006, "ibs_fetch:L1_ITLB_MISSES_L2_ITLB_HITS", "IBS L1 ITLB misses (and L2 ITLB hits)"),
+ IBS_EVENT(0xf007, "ibs_fetch:L1_ITLB_MISSES_L2_ITLB_MISSES", "IBS L1 L2 ITLB miss"),
+ IBS_EVENT(0xf008, "ibs_fetch:ICACHE_MISSES", "IBS instruction cache misses"),
+ IBS_EVENT(0xf009, "ibs_fetch:ICACHE_HITS", "IBS instruction cache hit"),
+ IBS_EVENT(0xf00a, "ibs_fetch:4K_PAGE", "IBS 4K page translation"),
+ IBS_EVENT(0xf00b, "ibs_fetch:2M_PAGE", "IBS 2M page translation"),
+ IBS_EVENT(0xf00c, "ibs_fetch:1G_PAGE", "IBS 1G page translation"),
+#if 0
+ IBS_EVENT(0xf00e, "ibs_fetch:LATENCY", "IBS fetch latency"),
+#endif
+ IBS_EVENT(0xf100, "ibs_op:ALL", "All IBS op samples"),
+#if 0
+ IBS_EVENT(0xf101, "ibs_op:TAG_TO_RETIRE", "IBS tag-to-retire cycles"),
+ IBS_EVENT(0xf102, "ibs_op:COMP_TO_RET", "IBS completion-to-retire cycles"),
+#endif
+ IBS_EVENT(0xf103, "ibs_op:BRANCH_RETIRED", "IBS branch op"),
+ IBS_EVENT(0xf104, "ibs_op:MISPREDICTED_BRANCH", "IBS mispredicted branch op"),
+ IBS_EVENT(0xf105, "ibs_op:TAKEN_BRANCH", "IBS taken branch op"),
+ IBS_EVENT(0xf106, "ibs_op:MISPREDICTED_BRANCH_TAKEN", "IBS mispredicted taken branch op"),
+ IBS_EVENT(0xf107, "ibs_op:RETURNS", "IBS return op"),
+ IBS_EVENT(0xf108, "ibs_op:MISPREDICTED_RETURNS", "IBS mispredicted return op"),
+ IBS_EVENT(0xf109, "ibs_op:RESYNC", "IBS resync op"),
+ IBS_EVENT(0xf200, "ibs_op:ALL_LOAD_STORE", "IBS all load store ops"),
+ IBS_EVENT(0xf201, "ibs_op:LOAD", "IBS load ops"),
+ IBS_EVENT(0xf202, "ibs_op:STORE", "IBS store ops"),
+ IBS_EVENT(0xf203, "ibs_op:L1_DTLB_HITS", "IBS L1 DTLB hit"),
+ IBS_EVENT(0xf204, "ibs_op:L1_DTLB_MISS_L2_DTLB_HIT", "IBS L1 DTLB misses L2 hits"),
+ IBS_EVENT(0xf205, "ibs_op:L1_L2_DTLB_MISS", "IBS L1 and L2 DTLB misses"),
+ IBS_EVENT(0xf206, "ibs_op:DATA_CACHE_MISS", "IBS data cache misses"),
+ IBS_EVENT(0xf207, "ibs_op:DATA_HITS", "IBS data cache hits"),
+ IBS_EVENT(0xf208, "ibs_op:MISALIGNED_DATA_ACC", "IBS misaligned data access"),
+ IBS_EVENT(0xf209, "ibs_op:BANK_CONF_LOAD", "IBS bank conflict on load op"),
+#if 0
+ IBS_EVENT(0xf20a, "ibs_op:BANK_CONF_STORE", "IBS bank conflict on store op"),
+#endif
+ IBS_EVENT(0xf20b, "ibs_op:FORWARD", "IBS store-to-load forwarded"),
+ IBS_EVENT(0xf20c, "ibs_op:CANCELLED", "IBS store-to-load cancelled"),
+ IBS_EVENT(0xf20d, "ibs_op:DCUC_MEM_ACC", "IBS UC memory access"),
+ IBS_EVENT(0xf20e, "ibs_op:DCWC_MEM_ACC", "IBS WC memory access"),
+ IBS_EVENT(0xf20f, "ibs_op:LOCKED", "IBS locked operation"),
+ IBS_EVENT(0xf210, "ibs_op:MAB_HIT", "IBS MAB hit"),
+ IBS_EVENT(0xf211, "ibs_op:L1_DTLB_4K", "IBS L1 DTLB 4K page"),
+ IBS_EVENT(0xf212, "ibs_op:L1_DTLB_2M", "IBS L1 DTLB 2M page"),
+ IBS_EVENT(0xf213, "ibs_op:L1_DTLB_1G", "IBS L1 DTLB 1G page"),
+ IBS_EVENT(0xf215, "ibs_op:L2_DTLB_4K", "IBS L2 DTLB 4K page"),
+ IBS_EVENT(0xf216, "ibs_op:L2_DTLB_2M", "IBS L2 DTLB 2M page"),
+#if 0
+ IBS_EVENT(0xf217, "ibs_op:L2_DTLB_1G", "IBS L2 DTLB 1G page"),
+ IBS_EVENT(0xf219, "ibs_op:DC_LOAD_LAT", "IBS data cache miss load latency"),
+#endif
+ IBS_EVENT(0xf240, "ibs_op:NB_LOCAL_ONLY", "IBS Northbridge local"),
+ IBS_EVENT(0xf241, "ibs_op:NB_REMOTE_ONLY", "IBS Northbridge remote"),
+ IBS_EVENT(0xf242, "ibs_op:NB_LOCAL_L3", "IBS Northbridge local L3"),
+ IBS_EVENT(0xf243, "ibs_op:NB_LOCAL_CACHE", "IBS Northbridge local core L1 or L2 cache"),
+ IBS_EVENT(0xf244, "ibs_op:NB_REMOTE_CACHE", "IBS Northbridge local core L1, L2, L3 cache"),
+ IBS_EVENT(0xf245, "ibs_op:NB_LOCAL_DRAM", "IBS Northbridge local DRAM"),
+ IBS_EVENT(0xf246, "ibs_op:NB_REMOTE_DRAM", "IBS Northbridge remote DRAM"),
+ IBS_EVENT(0xf247, "ibs_op:NB_LOCAL_OTHER", "IBS Northbridge local APIC MMIO Config PCI"),
+ IBS_EVENT(0xf248, "ibs_op:NB_REMOTE_OTHER", "IBS Northbridge remote APIC MMIO Config PCI"),
+ IBS_EVENT(0xf249, "ibs_op:NB_CACHE_MODIFIED", "IBS Northbridge cache modified state"),
+ IBS_EVENT(0xf24a, "ibs_op:NB_CACHE_OWNED", "IBS Northbridge cache owned state"),
+#if 0
+ IBS_EVENT(0xf24b, "ibs_op:NB_LOCAL_CACHE_LAT", "IBS Northbridge local cache latency"),
+ IBS_EVENT(0xf24c, "ibs_op:NB_REMOTE_CACHE_LAT", "IBS Northbridge remote cache latency"),
+#endif
+ { 0, NULL, NULL, { .filter = { IBS_FILTER_MATCH_ANY() } } }
};

static int ibs_parse_event(struct perf_event_attr *attr, char *sys, char *name)
{
- const char **event;
+ struct ibs_event *event;

if (strcmp("ibs_op", sys) && strcmp("ibs_fetch", sys))
return -ENOENT;

- for (event = events; *event; event++) {
- if (!strcmp(*event + strlen(sys) + 1, name))
+ for (event = events; event->id; event++) {
+ if (!strcmp(event->name + strlen(sys) + 1, name))
goto match;
}

return -EINVAL;
match:
+ /* pseudo event found */
+ attr->config1 = event->config;
attr->sample_type = PERF_SAMPLE_CPU;

return 0;
@@ -97,13 +391,14 @@ match:

static void ibs_print_events(const char *sys)
{
- const char **event;
+ struct ibs_event *event;

printf("\n");

- for (event = events; *event; event++) {
- if (!strncmp(sys, *event, strlen(sys)))
- printf(" %-50s [PMU event: %s]\n", *event, sys);
+ for (event = events; event->id; event++) {
+ if (!strncmp(sys, event->name, strlen(sys)))
+ printf(" %-50s [PMU event: %s, id:0x%x]\n",
+ event->name, sys, event->id);
}
}

--
1.7.8.4


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


peterz at infradead

May 7, 2012, 4:00 AM

Post #2 of 13 (271 views)
Permalink
Re: [PATCH 4/7] perf/x86-ibs: Add support for IBS pseudo events [In reply to]

On Wed, 2012-05-02 at 20:26 +0200, Robert Richter wrote:
> +enum ibs_filter_type {
> + IBS_NO_FILTER = 0,
> + IBS_MATCH_FILTER = 1,
> + IBS_ANY_SET_FILTER = 2,
> + IBS_PSEUDO_EVENT = 0x0F,
> +};
> +
> +struct ibs_filter {
> + struct {
> + u16 idx : 8;
> + u16 reserved : 4;
> + u16 type : 4;
> + };
> + union {
> + struct {
> + u8 mask;
> + u8 match;
> + };
> + u16 any;
> + };
> +};
> +
> +static bool
> +__perf_ibs_sample_matches(struct ibs_filter *filter, void *data, int size)
> +{
> + int left = size;
> +
> + switch (filter->type) {
> + case IBS_MATCH_FILTER:
> + left -= sizeof(u8);
> + break;
> + case IBS_ANY_SET_FILTER:
> + left -= sizeof(u16);
> + break;
> + default:
> + return false;
> + }
> +
> + left -= filter->idx;
> + if (left < 0)
> + return false;
> +
> + switch (filter->type) {
> + case IBS_MATCH_FILTER:
> + return ((*(u8*)(data + filter->idx)) & filter->mask) == filter->match;
> + case IBS_ANY_SET_FILTER:
> + return (*(u16*)(data + filter->idx)) & filter->any;
> + };
> +
> + return false;
> +}
> +
> +static bool perf_ibs_sample_matches(struct perf_event *event,
> + struct perf_ibs_data *data)
> +{
> + int i;
> + union {
> + struct ibs_filter filter[4];
> + u64 config[2];
> + } f;
> + struct ibs_filter *filter = f.filter;
> +
> + f.config[0] = event->attr.config1;
> + f.config[1] = event->attr.config2;
> +
> + for (i = 0; i < 4; i++, filter++) {
> + if (filter->type == IBS_NO_FILTER)
> + break;
> + if (!__perf_ibs_sample_matches(filter, data->regs, data->size))
> + return false;
> + }
> +
> + return true;
> +}

Who again wasn't decoding anything in perf_event_attr:config* ?

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


peterz at infradead

May 7, 2012, 5:08 AM

Post #3 of 13 (266 views)
Permalink
Re: [PATCH 4/7] perf/x86-ibs: Add support for IBS pseudo events [In reply to]

On Wed, 2012-05-02 at 20:26 +0200, Robert Richter wrote:

> This patch includes kernel and userland changes.
>
> Signed-off-by: Robert Richter <robert.richter [at] amd>
> ---
> arch/x86/kernel/cpu/perf_event_amd_ibs.c | 83 ++++++-
> tools/perf/util/pmu-ibs.c | 433 +++++++++++++++++++++++++-----

I think its best to separate this.

> 2 files changed, 445 insertions(+), 71 deletions(-)
>
> diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
> index 03743ad..1675479 100644
> --- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c
> +++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
> @@ -478,6 +478,81 @@ static struct perf_ibs perf_ibs_op = {
> .get_count = get_ibs_op_count,
> };
>
> +enum ibs_filter_type {
> + IBS_NO_FILTER = 0,
> + IBS_MATCH_FILTER = 1,
> + IBS_ANY_SET_FILTER = 2,
> + IBS_PSEUDO_EVENT = 0x0F,
> +};
> +
> +struct ibs_filter {
> + struct {
> + u16 idx : 8;
> + u16 reserved : 4;
> + u16 type : 4;
> + };
> + union {
> + struct {
> + u8 mask;
> + u8 match;
> + };
> + u16 any;
> + };
> +};

> diff --git a/tools/perf/util/pmu-ibs.c b/tools/perf/util/pmu-ibs.c
> index 07acb82..604cb8c 100644
> --- a/tools/perf/util/pmu-ibs.c
> +++ b/tools/perf/util/pmu-ibs.c


> +enum ibs_filter_type {
> + IBS_NO_FILTER = 0,
> + IBS_MATCH_FILTER = 1,
> + IBS_ANY_SET_FILTER = 2,
> + IBS_PSEUDO_EVENT = 0x0F,
> +};
> +
> +struct ibs_filter {
> + struct {
> + __u16 idx : 8;
> + __u16 reserved : 4;
> + __u16 type : 4;
> + };
> + union {
> + struct {
> + __u8 mask;
> + __u8 match;
> + };
> + __u16 any;
> + };
> +};

Having two copies of this just stinks, its only matter of time before
one receives changes the other doesn't.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


peterz at infradead

May 7, 2012, 6:03 AM

Post #4 of 13 (266 views)
Permalink
Re: [PATCH 4/7] perf/x86-ibs: Add support for IBS pseudo events [In reply to]

On Wed, 2012-05-02 at 20:26 +0200, Robert Richter wrote:
> +enum ibs_filter_type {
> + IBS_NO_FILTER = 0,
> + IBS_MATCH_FILTER = 1,
> + IBS_ANY_SET_FILTER = 2,
> + IBS_PSEUDO_EVENT = 0x0F,
> +};

I don't get how those pseudo events work, AFAIKT IBS_PSEUDO_EVENT causes
one to loose all events since it does have a filter set but fails the
filter and thus we skip the call to perf_event_overflow().

Furthermore, I think this filter stuff should accumulate the period so
that PERF_SAMPLE_PERIOD still works correctly and reflects the number of
counts since the last sample.

Also, what's the point of filtering in-kernel as opposed to doing all
this in userspace? Is the amount of data 'saved' significant enough?



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


robert.richter at amd

May 7, 2012, 7:47 AM

Post #5 of 13 (266 views)
Permalink
Re: [PATCH 4/7] perf/x86-ibs: Add support for IBS pseudo events [In reply to]

On 07.05.12 13:00:54, Peter Zijlstra wrote:
> Who again wasn't decoding anything in perf_event_attr:config* ?

attr:config is one of the ibs control msrs comparable with perfctr's
evntsel msr:

MSRC001_1030 IBS Fetch Control Register (IbsFetchCtl)
MSRC001_1033 IBS Execution Control Register (IbsOpCtl)

There are some options (randomisation, cycle/micro-op counting) but
usually it is null since the period is encoded in attr:period. But ibs
could be setup by an application using attr:config only which then
passes the value directly to the ctl msr.

-Robert

--
Advanced Micro Devices, Inc.
Operating System Research Center

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


peterz at infradead

May 7, 2012, 8:15 AM

Post #6 of 13 (265 views)
Permalink
Re: [PATCH 4/7] perf/x86-ibs: Add support for IBS pseudo events [In reply to]

On Mon, 2012-05-07 at 16:47 +0200, Robert Richter wrote:
> > Who again wasn't decoding anything in perf_event_attr:config* ?
>
> attr:config is one of the ibs control msrs comparable with perfctr's
> evntsel msr:
>
> MSRC001_1030 IBS Fetch Control Register (IbsFetchCtl)
> MSRC001_1033 IBS Execution Control Register (IbsOpCtl)

You missed reading a '*', even so:

> There are some options (randomisation, cycle/micro-op counting) but
> usually it is null since the period is encoded in attr:period. But ibs
> could be setup by an application using attr:config only which then
> passes the value directly to the ctl msr.

PMU_FORMAT_ATTR(IbsFetchMaxCnt, "config:0-15" );
PMU_FORMAT_ATTR(IbsFetchCnt, "config:16-31" );
PMU_FORMAT_ATTR(IbsFetchVal, "config:49" );
PMU_FORMAT_ATTR(IbsRandEn, "config:57" );

and

PMU_FORMAT_ATTR(IbsOpMaxCnt, "config:0-15" );
PMU_FORMAT_ATTR(IbsOpVal, "config:18" );
PMU_FORMAT_ATTR(IbsOpCntCtl, "config:19" ); /* subject to ibs_caps */

Are the writable bitfields of those two MSRs resp.

This patch adds:

PMU_FORMAT_ATTR(IbsFilter0Idx, "config1:0-7" );
PMU_FORMAT_ATTR(IbsFilter0Type, "config1:12-15" );
PMU_FORMAT_ATTR(IbsFilter0Mask, "config1:16-23" );
PMU_FORMAT_ATTR(IbsFilter0Match,"config1:24-31" );
PMU_FORMAT_ATTR(IbsFilter0Any, "config1:16-31" );

PMU_FORMAT_ATTR(IbsFilter1Idx, "config1:32-39" );
PMU_FORMAT_ATTR(IbsFilter1Type, "config1:44-47" );
PMU_FORMAT_ATTR(IbsFilter1Mask, "config1:48-55" );
PMU_FORMAT_ATTR(IbsFilter1Match,"config1:56-63" );
PMU_FORMAT_ATTR(IbsFilter1Any, "config1:48-63" );

PMU_FORMAT_ATTR(IbsFilter2Idx, "config2:0-7" );
PMU_FORMAT_ATTR(IbsFilter2Type, "config2:12-15" );
PMU_FORMAT_ATTR(IbsFilter2Mask, "config2:16-23" );
PMU_FORMAT_ATTR(IbsFilter2Match,"config2:24-31" );
PMU_FORMAT_ATTR(IbsFilter2Any, "config2:16-31" );

PMU_FORMAT_ATTR(IbsFilter3Idx, "config2:32-39" );
PMU_FORMAT_ATTR(IbsFilter3Type, "config2:44-47" );
PMU_FORMAT_ATTR(IbsFilter3Mask, "config2:48-55" );
PMU_FORMAT_ATTR(IbsFilter3Match,"config2:56-63" );
PMU_FORMAT_ATTR(IbsFilter3Any, "config2:48-63" );

And you can write your events like:

ibs_fetch/IbsFilter0Type=1,IbsFilter0Idx=48,IbsFilter0Mask=0x4,IbsFilter0Match=0x4/

No need to duplicate the struct and you're free to re-arrange the actual
bitfields if there ever is a need.

Even more, if you were to expose these events through sysfs
ibs_fetch/events/$foo you could modify the lot and it'd still all work.

No need to query cpuid to figure out if you're fam 10h+, no need to read
ibs_caps in userspace to figure out if config:19 is available, and no
need to duplicate that struct.

And don't tell me your config[12] fields are spec'ed somewhere..





--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


eranian at google

May 7, 2012, 8:21 AM

Post #7 of 13 (260 views)
Permalink
Re: [PATCH 4/7] perf/x86-ibs: Add support for IBS pseudo events [In reply to]

Robert,

There is something I don't quite understand with those pseudo-events.
Is it the case that by construction, it means you can only measure
on pseudo-event at a time? Supposed I want to look at cache-misses.
For each miss, I'd like to know where it missed, any TLB impacts. All
of that in one run with no multiplexing. Can I do this with your pseudo-events?



On Wed, May 2, 2012 at 8:26 PM, Robert Richter <robert.richter [at] amd> wrote:
> This patch implements support for IBS pseudo events. Pseudo events are
> derived from an IBS sample and determined through a combination of one
> or more IBS event flags or values. See here for a full description:
>
>  Software Optimization Guide for AMD Family 15h Processors
>  Appendix F Guide to Instruction-Based Sampling on AMD Family 15h Processors
>  Advanced Micro Devices, Inc.
>  Publication No. 47414, Revision 3.06
>  January 2012
>  http://support.amd.com/us/Processor_TechDocs/47414_15h_sw_opt_guide.pdf
>
> The list of supported events is provided by perf-list. A pseudo event
> can be set up like this:
>
>  # perf record -a -e ibs_op:MISPREDICTED_BRANCH ...
>
> The filter rules for IBS samples depending on a pseudo event are also
> described in the document above. The filter is setup in the perf tool
> pmu handler and passed to the kernel via config1/config2 attr values.
> The interface is extendable to pass the pseudo events directly to the
> kernel.
>
> There are some pseudo events capable to count latencies or other
> values. Counting values of such events is not yet supported.
>
> This patch includes kernel and userland changes.
>
> Signed-off-by: Robert Richter <robert.richter [at] amd>
> ---
>  arch/x86/kernel/cpu/perf_event_amd_ibs.c |   83 ++++++-
>  tools/perf/util/pmu-ibs.c                |  433 +++++++++++++++++++++++++-----
>  2 files changed, 445 insertions(+), 71 deletions(-)
>
> diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
> index 03743ad..1675479 100644
> --- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c
> +++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
> @@ -478,6 +478,81 @@ static struct perf_ibs perf_ibs_op = {
>        .get_count              = get_ibs_op_count,
>  };
>
> +enum ibs_filter_type {
> +       IBS_NO_FILTER           = 0,
> +       IBS_MATCH_FILTER        = 1,
> +       IBS_ANY_SET_FILTER      = 2,
> +       IBS_PSEUDO_EVENT        = 0x0F,
> +};
> +
> +struct ibs_filter {
> +       struct {
> +               u16             idx             : 8;
> +               u16             reserved        : 4;
> +               u16             type            : 4;
> +       };
> +       union {
> +               struct {
> +                       u8      mask;
> +                       u8      match;
> +               };
> +               u16             any;
> +       };
> +};
> +
> +static bool
> +__perf_ibs_sample_matches(struct ibs_filter *filter, void *data, int size)
> +{
> +       int left = size;
> +
> +       switch (filter->type) {
> +       case IBS_MATCH_FILTER:
> +               left -= sizeof(u8);
> +               break;
> +       case IBS_ANY_SET_FILTER:
> +               left -= sizeof(u16);
> +               break;
> +       default:
> +               return false;
> +       }
> +
> +       left -= filter->idx;
> +       if (left < 0)
> +               return false;
> +
> +       switch (filter->type) {
> +       case IBS_MATCH_FILTER:
> +               return ((*(u8*)(data + filter->idx)) & filter->mask) == filter->match;
> +       case IBS_ANY_SET_FILTER:
> +               return (*(u16*)(data + filter->idx)) & filter->any;
> +       };
> +
> +       return false;
> +}
> +
> +static bool perf_ibs_sample_matches(struct perf_event *event,
> +                                   struct perf_ibs_data *data)
> +{
> +       int i;
> +       union {
> +               struct ibs_filter filter[4];
> +               u64     config[2];
> +       } f;
> +       struct ibs_filter *filter = f.filter;
> +
> +       f.config[0] = event->attr.config1;
> +       f.config[1] = event->attr.config2;
> +
> +       for (i = 0; i < 4; i++, filter++) {
> +               if (filter->type == IBS_NO_FILTER)
> +                       break;
> +               if (!__perf_ibs_sample_matches(filter, data->regs, data->size))
> +                       return false;
> +       }
> +
> +       return true;
> +}
> +
>  static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
>  {
>        struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
> @@ -487,7 +562,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
>        struct perf_raw_record raw;
>        struct pt_regs regs;
>        struct perf_ibs_data ibs_data;
> -       int offset, size, check_rip, offset_max, throttle = 0;
> +       int offset, size, check_rip, filter, offset_max, throttle = 0;
>        unsigned int msr;
>        u64 *buf, *config, period;
>
> @@ -517,7 +592,8 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
>        size = 1;
>        offset = 1;
>        check_rip = (perf_ibs == &perf_ibs_op && (ibs_caps & IBS_CAPS_RIPINVALIDCHK));
> -       if (event->attr.sample_type & PERF_SAMPLE_RAW)
> +       filter = (event->attr.config1 != 0);
> +       if (filter || (event->attr.sample_type & PERF_SAMPLE_RAW))
>                offset_max = perf_ibs->offset_max;
>        else if (check_rip)
>                offset_max = 2;
> @@ -532,6 +608,9 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
>        } while (offset < offset_max);
>        ibs_data.size = sizeof(u64) * size;
>
> +       if (filter && !perf_ibs_sample_matches(event, &ibs_data))
> +               goto out;
> +
>        regs = *iregs;
>        if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) {
>                regs.flags &= ~PERF_EFLAGS_EXACT;
> diff --git a/tools/perf/util/pmu-ibs.c b/tools/perf/util/pmu-ibs.c
> index 07acb82..604cb8c 100644
> --- a/tools/perf/util/pmu-ibs.c
> +++ b/tools/perf/util/pmu-ibs.c
> @@ -12,84 +12,378 @@
>  #include <linux/compiler.h>
>  #include "pmu.h"
>
> -static const char *events[] = {
> -       "ibs_fetch:2M_PAGE",
> -       "ibs_fetch:4K_PAGE",
> -       "ibs_fetch:ABORTED",
> -       "ibs_fetch:ALL",
> -       "ibs_fetch:ATTEMPTED",
> -       "ibs_fetch:COMPLETED",
> -       "ibs_fetch:ICACHE_HITS",
> -       "ibs_fetch:ICACHE_MISSES",
> -       "ibs_fetch:ITLB_HITS",
> -       "ibs_fetch:KILLED",
> -       "ibs_fetch:L1_ITLB_MISSES_L2_ITLB_HITS",
> -       "ibs_fetch:L1_ITLB_MISSES_L2_ITLB_MISSES",
> -       "ibs_fetch:LATENCY",
> -       "ibs_op:ALL",
> -       "ibs_op:ALL_LOAD_STORE",
> -       "ibs_op:BANK_CONF_LOAD",
> -       "ibs_op:BANK_CONF_STORE",
> -       "ibs_op:BRANCH_RETIRED",
> -       "ibs_op:CANCELLED",
> -       "ibs_op:COMP_TO_RET",
> -       "ibs_op:DATA_CACHE_MISS",
> -       "ibs_op:DATA_HITS",
> -       "ibs_op:DC_LOAD_LAT",
> -       "ibs_op:DCUC_MEM_ACC",
> -       "ibs_op:DCWC_MEM_ACC",
> -       "ibs_op:FORWARD",
> -       "ibs_op:L1_DTLB_1G",
> -       "ibs_op:L1_DTLB_2M",
> -       "ibs_op:L1_DTLB_4K",
> -       "ibs_op:L1_DTLB_HITS",
> -       "ibs_op:L1_DTLB_MISS_L2_DTLB_HIT",
> -       "ibs_op:L1_L2_DTLB_MISS",
> -       "ibs_op:L2_DTLB_1G",
> -       "ibs_op:L2_DTLB_2M",
> -       "ibs_op:L2_DTLB_4K",
> -       "ibs_op:LOAD",
> -       "ibs_op:LOCKED",
> -       "ibs_op:MAB_HIT",
> -       "ibs_op:MISALIGNED_DATA_ACC",
> -       "ibs_op:MISPREDICTED_BRANCH",
> -       "ibs_op:MISPREDICTED_BRANCH_TAKEN",
> -       "ibs_op:MISPREDICTED_RETURNS",
> -       "ibs_op:NB_CACHE_MODIFIED",
> -       "ibs_op:NB_CACHE_OWNED",
> -       "ibs_op:NB_LOCAL_CACHE",
> -       "ibs_op:NB_LOCAL_CACHE_LAT",
> -       "ibs_op:NB_LOCAL_DRAM",
> -       "ibs_op:NB_LOCAL_L3",
> -       "ibs_op:NB_LOCAL_ONLY",
> -       "ibs_op:NB_LOCAL_OTHER",
> -       "ibs_op:NB_REMOTE_CACHE",
> -       "ibs_op:NB_REMOTE_CACHE_LAT",
> -       "ibs_op:NB_REMOTE_DRAM",
> -       "ibs_op:NB_REMOTE_ONLY",
> -       "ibs_op:NB_REMOTE_OTHER",
> -       "ibs_op:RESYNC",
> -       "ibs_op:RETURNS",
> -       "ibs_op:STORE",
> -       "ibs_op:TAG_TO_RETIRE",
> -       "ibs_op:TAKEN_BRANCH",
> -       NULL
> +enum ibs_filter_type {
> +       IBS_NO_FILTER           = 0,
> +       IBS_MATCH_FILTER        = 1,
> +       IBS_ANY_SET_FILTER      = 2,
> +       IBS_PSEUDO_EVENT        = 0x0F,
> +};
> +
> +struct ibs_filter {
> +       struct {
> +               __u16           idx             : 8;
> +               __u16           reserved        : 4;
> +               __u16           type            : 4;
> +       };
> +       union {
> +               struct {
> +                       __u8    mask;
> +                       __u8    match;
> +               };
> +               __u16           any;
> +       };
> +};
> +
> +struct ibs_event {
> +       __u16                   id;
> +       const char              *name;
> +       const char              *desc;
> +       union {
> +               __u16           pseudo_event;
> +               __u64           config;
> +               struct ibs_filter filter[2];
> +       };
> +};
> +
> +#define IBS_FETCH_CTL          0
> +#define IBS_OP_DATA            2
> +#define IBS_OP_DATA2           3
> +#define IBS_OP_DATA3           4
> +
> +#define IBS_IDX(reg, bit)      ((reg)<<3)+((bit)>>3)
> +#define IBS_MASK(bit, m)       (0xFF&m)
> +#define IBS_MASK16(bit, m)     (0xFFFF&m)
> +#define IBS_FILTER_MATCH_ANY() { { 0, 0, 0 }, { .any = 0 } }
> +
> +#define IBS_FILTER_ANY_SET(reg, bit, m)                                \
> +       {                                                       \
> +               {                                               \
> +               .type   = IBS_ANY_SET_FILTER,                   \
> +               .idx    = IBS_IDX(reg, bit),                    \
> +               .reserved = 0,                                  \
> +               },{                                             \
> +               .any    = IBS_MASK16(bit, m),                   \
> +               }                                               \
> +       },
> +
> +#define IBS_FILTER_ALL_CLEAR(reg, bit, m)                      \
> +       {                                                       \
> +               {                                               \
> +               .type   = IBS_MATCH_FILTER,                     \
> +               .idx    = IBS_IDX(reg, bit),                    \
> +               .reserved = 0,                                  \
> +               },{{                                            \
> +               .mask   = IBS_MASK(bit, m),                     \
> +               .match = 0,                                     \
> +               }}                                              \
> +       },                                                      \
> +       {                                                       \
> +               {                                               \
> +               .type   = IBS_MATCH_FILTER,                     \
> +               .idx    = IBS_IDX(reg, (bit) + 8),              \
> +               .reserved = 0,                                  \
> +               },{{                                            \
> +               .mask   = IBS_MASK(bit, (m) >> 8),              \
> +               .match  = 0,                                    \
> +               }}                                              \
> +       },
> +
> +#define IBS_FILTER_ALL_SET(reg, bit, m)                                \
> +       {                                                       \
> +               {                                               \
> +               .type   = IBS_MATCH_FILTER,                     \
> +               .idx    = IBS_IDX(reg, bit),                    \
> +               .reserved = 0,                                  \
> +               },{{                                            \
> +               .mask   = IBS_MASK(bit, m),                     \
> +               .match  = IBS_MASK(bit, m),                     \
> +               }}                                              \
> +       },
> +
> +#define IBS_FILTER_MATCH(reg, bit, m, v)                       \
> +       {                                                       \
> +               {                                               \
> +               .type   = IBS_MATCH_FILTER,                     \
> +               .idx    = IBS_IDX(reg, bit),                    \
> +               .reserved = 0,                                  \
> +               },{{                                            \
> +               .mask   = IBS_MASK(bit, m),                     \
> +               .match  = IBS_MASK(bit, v),                     \
> +               }}                                              \
> +       },
> +
> +#define IBS_FILTER_MATCH2(reg, reg2, bit, bit2, m, m2, v, v2)  \
> +       {                                                       \
> +               {                                               \
> +               .type   = IBS_MATCH_FILTER,                     \
> +               .idx    = IBS_IDX(reg, bit),                    \
> +               .reserved = 0,                                  \
> +               },{{                                            \
> +               .mask   = IBS_MASK(bit, m),                     \
> +               .match  = IBS_MASK(bit, v),                     \
> +               }}                                              \
> +       },                                                      \
> +       {                                                       \
> +               {                                               \
> +               .type   = IBS_MATCH_FILTER,                     \
> +               .idx    = IBS_IDX(reg2, bit2),                  \
> +               .reserved = 0,                                  \
> +               },{{                                            \
> +               .mask   = IBS_MASK(bit2, m2),                   \
> +               .match  = IBS_MASK(bit2, v2),                   \
> +               }}                                              \
> +       }
> +
> +#define IBS_EVENT(i, n, d)                                     \
> +       {                                                       \
> +               .id     = (i),                                  \
> +               .name   = (n),                                  \
> +               .desc   = (d),                                  \
> +               { .filter = { IBS_FILTER_##i } },               \
> +       }
> +#define IBS_FILTER(type, args...)              IBS_FILTER_##type(args)
> +
> +/*
> + * ID   Name                             Derivation
> + *
> + * F000 IBS fetch samples                Number of all IBS fetch samples
> + * F001 IBS fetch killed                 Number of killed IBS fetch samples
> + * F002 IBS fetch attempted              Number of non-killed IBS fetch samples
> + * F003 IBS fetch completed              IbsFetchComp
> + * F004 IBS fetch aborted                ~IbsFetchComp
> + * F005 IBS L1 ITLB hit                  ~IbsL1TlbMiss & IbsPhyAddrValid
> + * F006 IBS L1 ITLB miss, L2 ITLB hit    IbsL1TlbMiss & ~IbsL2TlbMiss
> + * F007 IBS L1 ITLB miss, L2 ITLB miss   IbsL1TlbMiss & IbsL2TlbMiss
> + * F008 IBS instruction cache miss       IbsIcMiss
> + * F009 IBS instruction cache hit        IbsFetchComp & ~IbsIcMiss
> + * F00A IBS 4K page translation          IbsL1TlbPgSz=0 & IbsPhyAddrValid
> + * F00B IBS 2M page translation          IbsL1TlbPgSz=1 & IbsPhyAddrValid
> + * F00C IBS 1G page translation          IbsL1TlbPgSz=2 & IbsPhyAddrValid
> + * F00D Reserved
> + * F00E IBS fetch latency                IbsfetchLat
> + */
> +#define IBS_FILTER_0xf000 IBS_FILTER(MATCH_ANY)
> +#define IBS_FILTER_0xf001 IBS_FILTER(ALL_CLEAR,        IBS_FETCH_CTL,  48, 0x019c)
> +#define IBS_FILTER_0xf002 IBS_FILTER(ANY_SET,  IBS_FETCH_CTL,  48, 0x019c)
> +#define IBS_FILTER_0xf003 IBS_FILTER(MATCH,    IBS_FETCH_CTL,  48, 0x04, 0x04)
> +#define IBS_FILTER_0xf004 IBS_FILTER(MATCH,    IBS_FETCH_CTL,  48, 0x04, 0x00)
> +#define IBS_FILTER_0xf005 IBS_FILTER(MATCH,    IBS_FETCH_CTL,  48, 0x90, 0x10)
> +#define IBS_FILTER_0xf006 IBS_FILTER(MATCH2,   IBS_FETCH_CTL, IBS_FETCH_CTL, 56, 48, 0x01, 0x80, 0x00, 0x80)
> +#define IBS_FILTER_0xf007 IBS_FILTER(MATCH2,   IBS_FETCH_CTL, IBS_FETCH_CTL, 56, 48, 0x01, 0x80, 0x01, 0x80)
> +#define IBS_FILTER_0xf008 IBS_FILTER(MATCH,    IBS_FETCH_CTL,  48, 0x08, 0x08)
> +#define IBS_FILTER_0xf009 IBS_FILTER(MATCH,    IBS_FETCH_CTL,  48, 0x0C, 0x04)
> +#define IBS_FILTER_0xf00a IBS_FILTER(MATCH,    IBS_FETCH_CTL,  48, 0x70, 0x10)
> +#define IBS_FILTER_0xf00b IBS_FILTER(MATCH,    IBS_FETCH_CTL,  48, 0x70, 0x30)
> +#define IBS_FILTER_0xf00c IBS_FILTER(MATCH,    IBS_FETCH_CTL,  48, 0x70, 0x60)
> +#if 0
> +#define IBS_FILTER_0xf00e IBS_FILTER(COUNT,    IBS_FETCH_CTL,  32, 0xffff)
> +#endif
> +
> +/*
> + * ID   Name                             Derivation
> + *
> + * F100 IBS all op samples               Number of all IBS op samples
> + * F101 IBS tag to retire cycles         Sum of all tag to retire cycles
> + * F102 ibs completion to retire cycles  Sum of all completion to retire cycles
> + * F103 IBS branch op                    IbsOpBrnRet
> + * F104 IBS mispredicted branch op       IbsOpBrnRet & IbsOpBrnMisp
> + * F105 IBS taken branch op              IbsOpBrnRet & IbsOpBrnTaken
> + * F106 IBS mispredicted taken branch op IbsOpBrnRet & IbsOpBrnTaken & IbsOpBrnMisp
> + * F107 IBS return op                    IbsOpReturn
> + * F108 IBS mispredicted return op       IbsOpReturn & IbsOpMispReturn
> + * F109 IBS resync op                    IbsOpBrnResync
> + */
> +#define IBS_FILTER_0xf100 IBS_FILTER(MATCH_ANY)
> +#if 0
> +#define IBS_FILTER_0xf101 IBS_FILTER(COUNT,    IBS_OP_DATA,    16, 0xffff)
> +#define IBS_FILTER_0xf102 IBS_FILTER(COUNT,    IBS_OP_DATA,     0, 0xffff)
> +#endif
> +#define IBS_FILTER_0xf103 IBS_FILTER(MATCH,    IBS_OP_DATA,    32, 0x20, 0x20)
> +#define IBS_FILTER_0xf104 IBS_FILTER(MATCH,    IBS_OP_DATA,    32, 0x30, 0x30)
> +#define IBS_FILTER_0xf105 IBS_FILTER(MATCH,    IBS_OP_DATA,    32, 0x28, 0x28)
> +#define IBS_FILTER_0xf106 IBS_FILTER(MATCH,    IBS_OP_DATA,    32, 0x38, 0x38)
> +#define IBS_FILTER_0xf107 IBS_FILTER(MATCH,    IBS_OP_DATA,    32, 0x04, 0x04)
> +#define IBS_FILTER_0xf108 IBS_FILTER(MATCH,    IBS_OP_DATA,    32, 0x06, 0x06)
> +#define IBS_FILTER_0xf109 IBS_FILTER(MATCH,    IBS_OP_DATA,    32, 0x01, 0x01)
> +
> +/*
> + * ID   Name                             Derivation
> + *
> + * F200 IBS All Load/Store Ops           IbsLdOp | IbsStOp
> + * F201 IBS Load Ops                     IbsLdOp
> + * F202 IBS Store Ops                    IbsStOp
> + * F203 IBS L1 DTLB Hit                  ~IbsDcL1tlbMiss & IbsDcLinAddrValid
> + * F204 IBS L1 DTLB Miss L2 DTLB Hit     IbsDcL1tlbMiss & ~IbsDcL2tlbMiss
> + * F205 IBS L1 DTLB Miss L2 DTLB Miss    IbsDcL1tlbMiss & IbsDcL2tlbMiss
> + * F206 IBS DC Miss                      IbsDcMiss
> + * F207 IBS DC Hit                       ~IbsDcMiss
> + * F208 IBS Misaligned Access            IbsDcMisAcc
> + * F209 IBS Bank Conflict On Load Op     IbsDcLdBnkCon
> + * F20A Reserved
> + * F20B IBS Store to Load Forwarded      IbsDcStToLdFwd
> + * F20C IBSStore to Load Forwarding Cancelled IbsDcStToLdCan
> + * F20D IBS UC memory access             IbsDcUcMemAcc
> + * F20E IBS WC memory access             IbsDcWcMemAcc
> + * F20F IBS locked operation             IbsDcLockedOp
> + * F210 IBS MAB hit                      IbsDcMabHit
> + * F211 IBS L1 DTLB 4K page              ~IbsDcL1tlbHit2M & ~IbsDcL1tlbHit1G &
> + *                                       IbsDcLinAddrValid
> + * F212 IBS L1 DTLB 2M page              IbsDcL1tlbHit2M & IbsDcLinAddrValid
> + * F213 IBS L1 DTLB 1G page              IbsDcL1tlbHit1G & IbsDcLinAddrValid
> + * F214 Reserved
> + * F215 IBS L2 DTLB 4K page              ~IbsDcL2tlbMiss & IbsDcL1tlbMiss &
> + *                                       ~IbsDcL1tlbHit2M & lbsDcLinAddrValid
> + * F216 IBS L2 DTLB 2M page              ~IbsDcL2tlbMiss & IbsDcL1tlbMiss &
> + *                                       IbsDcL1tlbHit2M & lbsDcLinAddrValid
> + * F217 Reserved
> + * F218 Reserved
> + * F219 IBS DC miss load latency         IbsDcMissLat when IbsLdOp & IbsDcMiss
> + */
> +#define IBS_FILTER_0xf200 IBS_FILTER(ANY_SET,  IBS_OP_DATA3,    0, 0x0003)
> +#define IBS_FILTER_0xf201 IBS_FILTER(MATCH,    IBS_OP_DATA3,    0, 0x01, 0x01)
> +#define IBS_FILTER_0xf202 IBS_FILTER(MATCH,    IBS_OP_DATA3,    0, 0x02, 0x02)
> +#define IBS_FILTER_0xf203 IBS_FILTER(MATCH2,   IBS_OP_DATA3, IBS_OP_DATA3, 16, 0, 0x02, 0x04, 0x02, 0x00)
> +#define IBS_FILTER_0xf204 IBS_FILTER(MATCH,    IBS_OP_DATA3,    0, 0x0C, 0x08)
> +#define IBS_FILTER_0xf205 IBS_FILTER(MATCH,    IBS_OP_DATA3,    0, 0x0C, 0x0C)
> +#define IBS_FILTER_0xf206 IBS_FILTER(MATCH,    IBS_OP_DATA3,    0, 0x80, 0x80)
> +#define IBS_FILTER_0xf207 IBS_FILTER(MATCH,    IBS_OP_DATA3,    0, 0x80, 0x00) IBS_FILTER(ANY_SET,   IBS_OP_DATA3,    0, 0x0003)
> +#define IBS_FILTER_0xf208 IBS_FILTER(MATCH,    IBS_OP_DATA3,    8, 0x01, 0x01)
> +#define IBS_FILTER_0xf209 IBS_FILTER(MATCH,    IBS_OP_DATA3,    8, 0x02, 0x02)
> +#define IBS_FILTER_0xf20b IBS_FILTER(MATCH,    IBS_OP_DATA3,    8, 0x08, 0x08)
> +#define IBS_FILTER_0xf20c IBS_FILTER(MATCH,    IBS_OP_DATA3,    8, 0x10, 0x10)
> +#define IBS_FILTER_0xf20d IBS_FILTER(MATCH,    IBS_OP_DATA3,    8, 0x40, 0x40)
> +#define IBS_FILTER_0xf20e IBS_FILTER(MATCH,    IBS_OP_DATA3,    8, 0x20, 0x20)
> +#define IBS_FILTER_0xf20f IBS_FILTER(MATCH,    IBS_OP_DATA3,    8, 0x80, 0x80)
> +#define IBS_FILTER_0xf210 IBS_FILTER(MATCH,    IBS_OP_DATA3,   16, 0x01, 0x01)
> +#define IBS_FILTER_0xf211 IBS_FILTER(MATCH2,   IBS_OP_DATA3, IBS_OP_DATA3, 16, 0, 0x02, 0x30, 0x02, 0x00)
> +#define IBS_FILTER_0xf212 IBS_FILTER(MATCH2,   IBS_OP_DATA3, IBS_OP_DATA3, 16, 0, 0x02, 0x10, 0x02, 0x10)
> +#define IBS_FILTER_0xf213 IBS_FILTER(MATCH2,   IBS_OP_DATA3, IBS_OP_DATA3, 16, 0, 0x02, 0x20, 0x02, 0x20)
> +#define IBS_FILTER_0xf215 IBS_FILTER(MATCH2,   IBS_OP_DATA3, IBS_OP_DATA3, 16, 0, 0x02, 0x1C, 0x02, 0x04)
> +#define IBS_FILTER_0xf216 IBS_FILTER(MATCH2,   IBS_OP_DATA3, IBS_OP_DATA3, 16, 0, 0x02, 0x1C, 0x02, 0x14)
> +#if 0
> +#define IBS_FILTER_0xf219 IBS_FILTER(COUNT,    IBS_OP_DATA3,   32, 0x00FFFF, 0x00FFFF)
> +#endif
> +
> +/*
> + * ID   Name                             Derivation
> + *
> + * F240 IBS NB local                     ~NbIbsReqDstProc
> + * F241 IBS NB remote                    NbIbsReqDstProc
> + * F242 IBS NB local L3                  NbIbsReqSrc=0x1 & ~NbIbsReqDstProc
> + * F243 IBS NB local L1/L2 (intercore)   NbIbsReqSrc=0x2 & ~NbIbsReqDstProc
> + * F244 IBS NB remote L1/L2/L3 cache     NbIbsReqSrc=0x2 & NbIbsReqDstProc
> + * F245 IBS NB local DRAM                NbIbsReqSrc=0x3 & ~NbIbsReqDstProc
> + * F246 IBS NB remote DRAM               NbIbsReqSrc=0x3 & NbIbsReqDstProc
> + * F247 IBS NB local other               NbIbsReqSrc=0x7 & ~NbIbsReqDstProc
> + * F248 IBS NB remote other              NbIbsReqSrc=0x7 & NbIbsReqDstProc
> + * F249 IBS NB cache M state             NbIbsReqSrc=0x2 & ~NbIbsReqCacheHitSt
> + * F24A IBS NB cache O state             NbIbsReqSrc=0x2 & NbIbsReqCacheHitSt
> + * F24B IBS NB local latency             IbsDcMissLat when ~NbIbsReqDstProc
> + * F24C IBS NB remote latency            IbsDcMissLat when NbIbsReqDstProc
> + */
> +#define IBS_FILTER_0xf240 IBS_FILTER(MATCH,    IBS_OP_DATA2,    0, 0x10, 0x00) IBS_FILTER(ANY_SET,     IBS_OP_DATA2,   0, 0x0007)
> +#define IBS_FILTER_0xf241 IBS_FILTER(MATCH,    IBS_OP_DATA2,    0, 0x10, 0x10) IBS_FILTER(ANY_SET,     IBS_OP_DATA2,   0, 0x0007)
> +#define IBS_FILTER_0xf242 IBS_FILTER(MATCH,    IBS_OP_DATA2,    0, 0x17, 0x01) IBS_FILTER(MATCH,       IBS_OP_DATA3,   0, 0x81, 0x81)
> +#define IBS_FILTER_0xf243 IBS_FILTER(MATCH,    IBS_OP_DATA2,    0, 0x17, 0x02) IBS_FILTER(MATCH,       IBS_OP_DATA3,   0, 0x81, 0x81)
> +#define IBS_FILTER_0xf244 IBS_FILTER(MATCH,    IBS_OP_DATA2,    0, 0x17, 0x12) IBS_FILTER(MATCH,       IBS_OP_DATA3,   0, 0x81, 0x81)
> +#define IBS_FILTER_0xf245 IBS_FILTER(MATCH,    IBS_OP_DATA2,    0, 0x17, 0x03) IBS_FILTER(MATCH,       IBS_OP_DATA3,   0, 0x81, 0x81)
> +#define IBS_FILTER_0xf246 IBS_FILTER(MATCH,    IBS_OP_DATA2,    0, 0x17, 0x13) IBS_FILTER(MATCH,       IBS_OP_DATA3,   0, 0x81, 0x81)
> +#define IBS_FILTER_0xf247 IBS_FILTER(MATCH,    IBS_OP_DATA2,    0, 0x17, 0x07) IBS_FILTER(MATCH,       IBS_OP_DATA3,   0, 0x81, 0x81)
> +#define IBS_FILTER_0xf248 IBS_FILTER(MATCH,    IBS_OP_DATA2,    0, 0x17, 0x17) IBS_FILTER(MATCH,       IBS_OP_DATA3,   0, 0x81, 0x81)
> +#define IBS_FILTER_0xf249 IBS_FILTER(MATCH,    IBS_OP_DATA2,    0, 0x27, 0x02) IBS_FILTER(MATCH,       IBS_OP_DATA3,   0, 0x81, 0x81)
> +#define IBS_FILTER_0xf24a IBS_FILTER(MATCH,    IBS_OP_DATA2,    0, 0x27, 0x22) IBS_FILTER(MATCH,       IBS_OP_DATA3,   0, 0x81, 0x81)
> +
> +static struct ibs_event events[] = {
> +       IBS_EVENT(0xf000, "ibs_fetch:ALL", "All IBS fetch samples"),
> +       IBS_EVENT(0xf001, "ibs_fetch:KILLED", "IBS fetch killed"),
> +       IBS_EVENT(0xf002, "ibs_fetch:ATTEMPTED", "IBS fetch attempted"),
> +       IBS_EVENT(0xf003, "ibs_fetch:COMPLETED", "IBS fetch completed"),
> +       IBS_EVENT(0xf004, "ibs_fetch:ABORTED", "IBS fetch aborted"),
> +       IBS_EVENT(0xf005, "ibs_fetch:ITLB_HITS", "IBS ITLB hit"),
> +       IBS_EVENT(0xf006, "ibs_fetch:L1_ITLB_MISSES_L2_ITLB_HITS", "IBS L1 ITLB misses (and L2 ITLB hits)"),
> +       IBS_EVENT(0xf007, "ibs_fetch:L1_ITLB_MISSES_L2_ITLB_MISSES", "IBS L1 L2 ITLB miss"),
> +       IBS_EVENT(0xf008, "ibs_fetch:ICACHE_MISSES", "IBS instruction cache misses"),
> +       IBS_EVENT(0xf009, "ibs_fetch:ICACHE_HITS", "IBS instruction cache hit"),
> +       IBS_EVENT(0xf00a, "ibs_fetch:4K_PAGE", "IBS 4K page translation"),
> +       IBS_EVENT(0xf00b, "ibs_fetch:2M_PAGE", "IBS 2M page translation"),
> +       IBS_EVENT(0xf00c, "ibs_fetch:1G_PAGE", "IBS 1G page translation"),
> +#if 0
> +       IBS_EVENT(0xf00e, "ibs_fetch:LATENCY", "IBS fetch latency"),
> +#endif
> +       IBS_EVENT(0xf100, "ibs_op:ALL", "All IBS op samples"),
> +#if 0
> +       IBS_EVENT(0xf101, "ibs_op:TAG_TO_RETIRE", "IBS tag-to-retire cycles"),
> +       IBS_EVENT(0xf102, "ibs_op:COMP_TO_RET", "IBS completion-to-retire cycles"),
> +#endif
> +       IBS_EVENT(0xf103, "ibs_op:BRANCH_RETIRED", "IBS branch op"),
> +       IBS_EVENT(0xf104, "ibs_op:MISPREDICTED_BRANCH", "IBS mispredicted branch op"),
> +       IBS_EVENT(0xf105, "ibs_op:TAKEN_BRANCH", "IBS taken branch op"),
> +       IBS_EVENT(0xf106, "ibs_op:MISPREDICTED_BRANCH_TAKEN", "IBS mispredicted taken branch op"),
> +       IBS_EVENT(0xf107, "ibs_op:RETURNS", "IBS return op"),
> +       IBS_EVENT(0xf108, "ibs_op:MISPREDICTED_RETURNS", "IBS mispredicted return op"),
> +       IBS_EVENT(0xf109, "ibs_op:RESYNC", "IBS resync op"),
> +       IBS_EVENT(0xf200, "ibs_op:ALL_LOAD_STORE", "IBS all load store ops"),
> +       IBS_EVENT(0xf201, "ibs_op:LOAD", "IBS load ops"),
> +       IBS_EVENT(0xf202, "ibs_op:STORE", "IBS store ops"),
> +       IBS_EVENT(0xf203, "ibs_op:L1_DTLB_HITS", "IBS L1 DTLB hit"),
> +       IBS_EVENT(0xf204, "ibs_op:L1_DTLB_MISS_L2_DTLB_HIT", "IBS L1 DTLB misses L2 hits"),
> +       IBS_EVENT(0xf205, "ibs_op:L1_L2_DTLB_MISS", "IBS L1 and L2 DTLB misses"),
> +       IBS_EVENT(0xf206, "ibs_op:DATA_CACHE_MISS", "IBS data cache misses"),
> +       IBS_EVENT(0xf207, "ibs_op:DATA_HITS", "IBS data cache hits"),
> +       IBS_EVENT(0xf208, "ibs_op:MISALIGNED_DATA_ACC", "IBS misaligned data access"),
> +       IBS_EVENT(0xf209, "ibs_op:BANK_CONF_LOAD", "IBS bank conflict on load op"),
> +#if 0
> +       IBS_EVENT(0xf20a, "ibs_op:BANK_CONF_STORE", "IBS bank conflict on store op"),
> +#endif
> +       IBS_EVENT(0xf20b, "ibs_op:FORWARD", "IBS store-to-load forwarded"),
> +       IBS_EVENT(0xf20c, "ibs_op:CANCELLED", "IBS store-to-load cancelled"),
> +       IBS_EVENT(0xf20d, "ibs_op:DCUC_MEM_ACC", "IBS UC memory access"),
> +       IBS_EVENT(0xf20e, "ibs_op:DCWC_MEM_ACC", "IBS WC memory access"),
> +       IBS_EVENT(0xf20f, "ibs_op:LOCKED", "IBS locked operation"),
> +       IBS_EVENT(0xf210, "ibs_op:MAB_HIT", "IBS MAB hit"),
> +       IBS_EVENT(0xf211, "ibs_op:L1_DTLB_4K", "IBS L1 DTLB 4K page"),
> +       IBS_EVENT(0xf212, "ibs_op:L1_DTLB_2M", "IBS L1 DTLB 2M page"),
> +       IBS_EVENT(0xf213, "ibs_op:L1_DTLB_1G", "IBS L1 DTLB 1G page"),
> +       IBS_EVENT(0xf215, "ibs_op:L2_DTLB_4K", "IBS L2 DTLB 4K page"),
> +       IBS_EVENT(0xf216, "ibs_op:L2_DTLB_2M", "IBS L2 DTLB 2M page"),
> +#if 0
> +       IBS_EVENT(0xf217, "ibs_op:L2_DTLB_1G", "IBS L2 DTLB 1G page"),
> +       IBS_EVENT(0xf219, "ibs_op:DC_LOAD_LAT", "IBS data cache miss load latency"),
> +#endif
> +       IBS_EVENT(0xf240, "ibs_op:NB_LOCAL_ONLY", "IBS Northbridge local"),
> +       IBS_EVENT(0xf241, "ibs_op:NB_REMOTE_ONLY", "IBS Northbridge remote"),
> +       IBS_EVENT(0xf242, "ibs_op:NB_LOCAL_L3", "IBS Northbridge local L3"),
> +       IBS_EVENT(0xf243, "ibs_op:NB_LOCAL_CACHE", "IBS Northbridge local core L1 or L2 cache"),
> +       IBS_EVENT(0xf244, "ibs_op:NB_REMOTE_CACHE", "IBS Northbridge local core L1, L2, L3 cache"),
> +       IBS_EVENT(0xf245, "ibs_op:NB_LOCAL_DRAM", "IBS Northbridge local DRAM"),
> +       IBS_EVENT(0xf246, "ibs_op:NB_REMOTE_DRAM", "IBS Northbridge remote DRAM"),
> +       IBS_EVENT(0xf247, "ibs_op:NB_LOCAL_OTHER", "IBS Northbridge local APIC MMIO Config PCI"),
> +       IBS_EVENT(0xf248, "ibs_op:NB_REMOTE_OTHER", "IBS Northbridge remote APIC MMIO Config PCI"),
> +       IBS_EVENT(0xf249, "ibs_op:NB_CACHE_MODIFIED", "IBS Northbridge cache modified state"),
> +       IBS_EVENT(0xf24a, "ibs_op:NB_CACHE_OWNED", "IBS Northbridge cache owned state"),
> +#if 0
> +       IBS_EVENT(0xf24b, "ibs_op:NB_LOCAL_CACHE_LAT", "IBS Northbridge local cache latency"),
> +       IBS_EVENT(0xf24c, "ibs_op:NB_REMOTE_CACHE_LAT", "IBS Northbridge remote cache latency"),
> +#endif
> +       { 0, NULL, NULL, { .filter = { IBS_FILTER_MATCH_ANY() } } }
>  };
>
>  static int ibs_parse_event(struct perf_event_attr *attr, char *sys, char *name)
>  {
> -       const char **event;
> +       struct ibs_event *event;
>
>        if (strcmp("ibs_op", sys) && strcmp("ibs_fetch", sys))
>                return -ENOENT;
>
> -       for (event = events; *event; event++) {
> -               if (!strcmp(*event + strlen(sys) + 1, name))
> +       for (event = events; event->id; event++) {
> +               if (!strcmp(event->name + strlen(sys) + 1, name))
>                        goto match;
>        }
>
>        return -EINVAL;
>  match:
> +       /* pseudo event found */
> +       attr->config1 = event->config;
>        attr->sample_type = PERF_SAMPLE_CPU;
>
>        return 0;
> @@ -97,13 +391,14 @@ match:
>
>  static void ibs_print_events(const char *sys)
>  {
> -       const char **event;
> +       struct ibs_event *event;
>
>        printf("\n");
>
> -       for (event = events; *event; event++) {
> -               if (!strncmp(sys, *event, strlen(sys)))
> -                       printf("  %-50s [PMU event: %s]\n", *event, sys);
> +       for (event = events; event->id; event++) {
> +               if (!strncmp(sys, event->name, strlen(sys)))
> +                       printf("  %-50s [PMU event: %s, id:0x%x]\n",
> +                              event->name, sys, event->id);
>        }
>  }
>
> --
> 1.7.8.4
>
>
NrybXǧv^)޺{.n+{zXܨ}Ơz&j:+vzZ++zfh~izw?&)ߢf^jǫym@Aa 0hi


peterz at infradead

May 7, 2012, 8:29 AM

Post #8 of 13 (262 views)
Permalink
Re: [PATCH 4/7] perf/x86-ibs: Add support for IBS pseudo events [In reply to]

On Mon, 2012-05-07 at 17:21 +0200, Stephane Eranian wrote:
> There is something I don't quite understand with those pseudo-events.
> Is it the case that by construction, it means you can only measure
> on pseudo-event at a time? Supposed I want to look at cache-misses.
> For each miss, I'd like to know where it missed, any TLB impacts. All
> of that in one run with no multiplexing. Can I do this with your
> pseudo-events?
>
Not from how I read the patch, a pseudo event will count as a full event
and since the IBS things only have a single thing its full.

If you want multiple of these you'd have to get the raw stream and demux
in userspace.



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


robert.richter at amd

May 7, 2012, 8:44 AM

Post #9 of 13 (261 views)
Permalink
Re: [PATCH 4/7] perf/x86-ibs: Add support for IBS pseudo events [In reply to]

On 07.05.12 15:03:02, Peter Zijlstra wrote:
> On Wed, 2012-05-02 at 20:26 +0200, Robert Richter wrote:
> > +enum ibs_filter_type {
> > + IBS_NO_FILTER = 0,
> > + IBS_MATCH_FILTER = 1,
> > + IBS_ANY_SET_FILTER = 2,
> > + IBS_PSEUDO_EVENT = 0x0F,
> > +};
>
> I don't get how those pseudo events work, AFAIKT IBS_PSEUDO_EVENT causes
> one to loose all events since it does have a filter set but fails the
> filter and thus we skip the call to perf_event_overflow().

You periodically (fix clk cycles or number of micro-ops) trigger IBS
samples and afterwards analyses the samples for certain filter rules
(see rule description in pmu-ibs.c).

> Furthermore, I think this filter stuff should accumulate the period so
> that PERF_SAMPLE_PERIOD still works correctly and reflects the number of
> counts since the last sample.

Yes, simply dropping the sample is not enough. Have to check if the
period is correctly maintained.

> Also, what's the point of filtering in-kernel as opposed to doing all
> this in userspace? Is the amount of data 'saved' significant enough?

In-kernel filtering has drawbacks esp. if you want to handle multiple
pseudo-events and also when post-processing a perf.data file. But for
a proof-of-concept and a demonstration it was the easiest
implementation since there is a lack of userland filtering. I guess I
will look at how to implement this.

-Robert

--
Advanced Micro Devices, Inc.
Operating System Research Center

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


peterz at infradead

May 7, 2012, 8:51 AM

Post #10 of 13 (260 views)
Permalink
Re: [PATCH 4/7] perf/x86-ibs: Add support for IBS pseudo events [In reply to]

On Mon, 2012-05-07 at 17:44 +0200, Robert Richter wrote:
> On 07.05.12 15:03:02, Peter Zijlstra wrote:
> > On Wed, 2012-05-02 at 20:26 +0200, Robert Richter wrote:
> > > +enum ibs_filter_type {
> > > + IBS_NO_FILTER = 0,
> > > + IBS_MATCH_FILTER = 1,
> > > + IBS_ANY_SET_FILTER = 2,
> > > + IBS_PSEUDO_EVENT = 0x0F,
> > > +};
> >
> > I don't get how those pseudo events work, AFAIKT IBS_PSEUDO_EVENT causes
> > one to loose all events since it does have a filter set but fails the
> > filter and thus we skip the call to perf_event_overflow().
>
> You periodically (fix clk cycles or number of micro-ops) trigger IBS
> samples and afterwards analyses the samples for certain filter rules
> (see rule description in pmu-ibs.c).

But IBS_PSEUDO_EVENT will fail all filter test and you'll end up with
exactly 0 samples. Still somewhat confused..

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


robert.richter at amd

May 7, 2012, 8:52 AM

Post #11 of 13 (260 views)
Permalink
Re: [PATCH 4/7] perf/x86-ibs: Add support for IBS pseudo events [In reply to]

On 07.05.12 17:29:17, Peter Zijlstra wrote:
> On Mon, 2012-05-07 at 17:21 +0200, Stephane Eranian wrote:
> > There is something I don't quite understand with those pseudo-events.
> > Is it the case that by construction, it means you can only measure
> > on pseudo-event at a time? Supposed I want to look at cache-misses.
> > For each miss, I'd like to know where it missed, any TLB impacts. All
> > of that in one run with no multiplexing. Can I do this with your
> > pseudo-events?
> >
> Not from how I read the patch, a pseudo event will count as a full event
> and since the IBS things only have a single thing its full.
>
> If you want multiple of these you'd have to get the raw stream and demux
> in userspace.

As said in my previous mail, this is a drawback. And as with
precise-rip it is better to implement this in userland.

The question here is how to implement it. You need the event option
string (-e) not only to setup the syscall but also for userspace
post-processing. Any hint for something similar already done in perf?

Thanks,

-Robert

--
Advanced Micro Devices, Inc.
Operating System Research Center

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


robert.richter at amd

May 7, 2012, 8:58 AM

Post #12 of 13 (260 views)
Permalink
Re: [PATCH 4/7] perf/x86-ibs: Add support for IBS pseudo events [In reply to]

On 07.05.12 17:51:51, Peter Zijlstra wrote:
> On Mon, 2012-05-07 at 17:44 +0200, Robert Richter wrote:
> > On 07.05.12 15:03:02, Peter Zijlstra wrote:
> > > On Wed, 2012-05-02 at 20:26 +0200, Robert Richter wrote:
> > > > +enum ibs_filter_type {
> > > > + IBS_NO_FILTER = 0,
> > > > + IBS_MATCH_FILTER = 1,
> > > > + IBS_ANY_SET_FILTER = 2,
> > > > + IBS_PSEUDO_EVENT = 0x0F,
> > > > +};
> > >
> > > I don't get how those pseudo events work, AFAIKT IBS_PSEUDO_EVENT causes
> > > one to loose all events since it does have a filter set but fails the
> > > filter and thus we skip the call to perf_event_overflow().
> >
> > You periodically (fix clk cycles or number of micro-ops) trigger IBS
> > samples and afterwards analyses the samples for certain filter rules
> > (see rule description in pmu-ibs.c).
>
> But IBS_PSEUDO_EVENT will fail all filter test and you'll end up with
> exactly 0 samples. Still somewhat confused..

Ahh, got your question. This is a place holder for writing the pseudo
event id's (0xF000 mask) directly in config[12]. But this is not yet
implemented. And since we probably all prefer userland filtering we
just don't need this at all.

-Robert

--
Advanced Micro Devices, Inc.
Operating System Research Center

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/


robert.richter at amd

May 7, 2012, 9:03 AM

Post #13 of 13 (263 views)
Permalink
Re: [PATCH 4/7] perf/x86-ibs: Add support for IBS pseudo events [In reply to]

On 07.05.12 17:15:18, Peter Zijlstra wrote:
> On Mon, 2012-05-07 at 16:47 +0200, Robert Richter wrote:
> > > Who again wasn't decoding anything in perf_event_attr:config* ?
> >
> > attr:config is one of the ibs control msrs comparable with perfctr's
> > evntsel msr:
> >
> > MSRC001_1030 IBS Fetch Control Register (IbsFetchCtl)
> > MSRC001_1033 IBS Execution Control Register (IbsOpCtl)
>
> You missed reading a '*', even so:
>
> > There are some options (randomisation, cycle/micro-op counting) but
> > usually it is null since the period is encoded in attr:period. But ibs
> > could be setup by an application using attr:config only which then
> > passes the value directly to the ctl msr.
>
> PMU_FORMAT_ATTR(IbsFetchMaxCnt, "config:0-15" );
> PMU_FORMAT_ATTR(IbsFetchCnt, "config:16-31" );
> PMU_FORMAT_ATTR(IbsFetchVal, "config:49" );
> PMU_FORMAT_ATTR(IbsRandEn, "config:57" );
>
> and
>
> PMU_FORMAT_ATTR(IbsOpMaxCnt, "config:0-15" );
> PMU_FORMAT_ATTR(IbsOpVal, "config:18" );
> PMU_FORMAT_ATTR(IbsOpCntCtl, "config:19" ); /* subject to ibs_caps */
>
> Are the writable bitfields of those two MSRs resp.
>
> This patch adds:
>
> PMU_FORMAT_ATTR(IbsFilter0Idx, "config1:0-7" );
> PMU_FORMAT_ATTR(IbsFilter0Type, "config1:12-15" );
> PMU_FORMAT_ATTR(IbsFilter0Mask, "config1:16-23" );
> PMU_FORMAT_ATTR(IbsFilter0Match,"config1:24-31" );
> PMU_FORMAT_ATTR(IbsFilter0Any, "config1:16-31" );
>

Yes, let's take this format specification for config and drop kernel
side filtering in config[12].

Passing options like IbsRandEn was another open item. This is a nice
solution for this.

-Robert

--
Advanced Micro Devices, Inc.
Operating System Research Center

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo [at] vger
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Linux kernel RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.