Commit 0feb40e6 authored by 4ast's avatar 4ast Committed by GitHub

Merge pull request #1192 from palmtenor/perf_config

Unify Perf Event related Enums and checks
parents cce028d8 f510b6b7
...@@ -604,10 +604,32 @@ error: ...@@ -604,10 +604,32 @@ error:
return NULL; return NULL;
} }
int invalid_perf_config(uint32_t type, uint64_t config) {
switch (type) {
case PERF_TYPE_HARDWARE:
return config >= PERF_COUNT_HW_MAX;
case PERF_TYPE_SOFTWARE:
return config >= PERF_COUNT_SW_MAX;
case PERF_TYPE_RAW:
return 0;
default:
return 1;
}
}
int bpf_open_perf_event(uint32_t type, uint64_t config, int pid, int cpu) { int bpf_open_perf_event(uint32_t type, uint64_t config, int pid, int cpu) {
int fd; int fd;
struct perf_event_attr attr = {}; struct perf_event_attr attr = {};
if (type != PERF_TYPE_HARDWARE && type != PERF_TYPE_RAW) {
fprintf(stderr, "Unsupported perf event type\n");
return -1;
}
if (invalid_perf_config(type, config)) {
fprintf(stderr, "Invalid perf event config\n");
return -1;
}
attr.sample_period = LONG_MAX; attr.sample_period = LONG_MAX;
attr.type = type; attr.type = type;
attr.config = config; attr.config = config;
...@@ -733,8 +755,7 @@ int bpf_attach_perf_event(int progfd, uint32_t ev_type, uint32_t ev_config, ...@@ -733,8 +755,7 @@ int bpf_attach_perf_event(int progfd, uint32_t ev_type, uint32_t ev_config,
fprintf(stderr, "Unsupported perf event type\n"); fprintf(stderr, "Unsupported perf event type\n");
return -1; return -1;
} }
if ((ev_type == PERF_TYPE_HARDWARE && ev_config >= PERF_COUNT_HW_MAX) || if (invalid_perf_config(ev_type, ev_config)) {
(ev_type == PERF_TYPE_SOFTWARE && ev_config >= PERF_COUNT_SW_MAX)) {
fprintf(stderr, "Invalid perf event config\n"); fprintf(stderr, "Invalid perf event config\n");
return -1; return -1;
} }
......
...@@ -468,41 +468,6 @@ class ProgArray(ArrayBase): ...@@ -468,41 +468,6 @@ class ProgArray(ArrayBase):
raise Exception("Could not delete item") raise Exception("Could not delete item")
class PerfEventArray(ArrayBase): class PerfEventArray(ArrayBase):
class Event(object):
def __init__(self, typ, config):
self.typ = typ
self.config = config
HW_CPU_CYCLES = Event(Perf.PERF_TYPE_HARDWARE, 0)
HW_INSTRUCTIONS = Event(Perf.PERF_TYPE_HARDWARE, 1)
HW_CACHE_REFERENCES = Event(Perf.PERF_TYPE_HARDWARE, 2)
HW_CACHE_MISSES = Event(Perf.PERF_TYPE_HARDWARE, 3)
HW_BRANCH_INSTRUCTIONS = Event(Perf.PERF_TYPE_HARDWARE, 4)
HW_BRANCH_MISSES = Event(Perf.PERF_TYPE_HARDWARE, 5)
HW_BUS_CYCLES = Event(Perf.PERF_TYPE_HARDWARE, 6)
HW_STALLED_CYCLES_FRONTEND = Event(Perf.PERF_TYPE_HARDWARE, 7)
HW_STALLED_CYCLES_BACKEND = Event(Perf.PERF_TYPE_HARDWARE, 8)
HW_REF_CPU_CYCLES = Event(Perf.PERF_TYPE_HARDWARE, 9)
# not yet supported, wip
#HW_CACHE_L1D_READ = Event(Perf.PERF_TYPE_HW_CACHE, 0<<0|0<<8|0<<16)
#HW_CACHE_L1D_READ_MISS = Event(Perf.PERF_TYPE_HW_CACHE, 0<<0|0<<8|1<<16)
#HW_CACHE_L1D_WRITE = Event(Perf.PERF_TYPE_HW_CACHE, 0<<0|1<<8|0<<16)
#HW_CACHE_L1D_WRITE_MISS = Event(Perf.PERF_TYPE_HW_CACHE, 0<<0|1<<8|1<<16)
#HW_CACHE_L1D_PREF = Event(Perf.PERF_TYPE_HW_CACHE, 0<<0|2<<8|0<<16)
#HW_CACHE_L1D_PREF_MISS = Event(Perf.PERF_TYPE_HW_CACHE, 0<<0|2<<8|1<<16)
#HW_CACHE_L1I_READ = Event(Perf.PERF_TYPE_HW_CACHE, 1<<0|0<<8|0<<16)
#HW_CACHE_L1I_READ_MISS = Event(Perf.PERF_TYPE_HW_CACHE, 1<<0|0<<8|1<<16)
#HW_CACHE_L1I_WRITE = Event(Perf.PERF_TYPE_HW_CACHE, 1<<0|1<<8|0<<16)
#HW_CACHE_L1I_WRITE_MISS = Event(Perf.PERF_TYPE_HW_CACHE, 1<<0|1<<8|1<<16)
#HW_CACHE_L1I_PREF = Event(Perf.PERF_TYPE_HW_CACHE, 1<<0|2<<8|0<<16)
#HW_CACHE_L1I_PREF_MISS = Event(Perf.PERF_TYPE_HW_CACHE, 1<<0|2<<8|1<<16)
#HW_CACHE_LL_READ = Event(Perf.PERF_TYPE_HW_CACHE, 2<<0|0<<8|0<<16)
#HW_CACHE_LL_READ_MISS = Event(Perf.PERF_TYPE_HW_CACHE, 2<<0|0<<8|1<<16)
#HW_CACHE_LL_WRITE = Event(Perf.PERF_TYPE_HW_CACHE, 2<<0|1<<8|0<<16)
#HW_CACHE_LL_WRITE_MISS = Event(Perf.PERF_TYPE_HW_CACHE, 2<<0|1<<8|1<<16)
#HW_CACHE_LL_PREF = Event(Perf.PERF_TYPE_HW_CACHE, 2<<0|2<<8|0<<16)
#HW_CACHE_LL_PREF_MISS = Event(Perf.PERF_TYPE_HW_CACHE, 2<<0|2<<8|1<<16)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(PerfEventArray, self).__init__(*args, **kwargs) super(PerfEventArray, self).__init__(*args, **kwargs)
...@@ -556,18 +521,15 @@ class PerfEventArray(ArrayBase): ...@@ -556,18 +521,15 @@ class PerfEventArray(ArrayBase):
# the fd is kept open in the map itself by the kernel # the fd is kept open in the map itself by the kernel
os.close(fd) os.close(fd)
def open_perf_event(self, ev): def open_perf_event(self, typ, config):
"""open_perf_event(ev) """open_perf_event(typ, config)
Configures the table such that calls from the bpf program to Configures the table such that calls from the bpf program to
table.perf_read(bpf_get_smp_processor_id()) will return the hardware table.perf_read(bpf_get_smp_processor_id()) will return the hardware
counter denoted by event ev on the local cpu. counter denoted by event ev on the local cpu.
""" """
if not isinstance(ev, self.Event):
raise Exception("argument must be an Event, got %s", type(ev))
for i in get_online_cpus(): for i in get_online_cpus():
self._open_perf_event(i, ev.typ, ev.config) self._open_perf_event(i, typ, config)
class PerCpuHash(HashTable): class PerCpuHash(HashTable):
......
...@@ -18,12 +18,20 @@ BPF_HISTOGRAM(dist); ...@@ -18,12 +18,20 @@ BPF_HISTOGRAM(dist);
int kprobe__sys_getuid(void *ctx) { int kprobe__sys_getuid(void *ctx) {
u32 cpu = bpf_get_smp_processor_id(); u32 cpu = bpf_get_smp_processor_id();
u64 val = cnt1.perf_read(cpu); u64 val = cnt1.perf_read(cpu);
if (((s64)val < 0) && ((s64)val > -256))
return 0;
prev.update(&cpu, &val); prev.update(&cpu, &val);
return 0; return 0;
} }
int kretprobe__sys_getuid(void *ctx) { int kretprobe__sys_getuid(void *ctx) {
u32 cpu = bpf_get_smp_processor_id(); u32 cpu = bpf_get_smp_processor_id();
u64 val = cnt1.perf_read(cpu); u64 val = cnt1.perf_read(cpu);
if (((s64)val < 0) && ((s64)val > -256))
return 0;
u64 *prevp = prev.lookup(&cpu); u64 *prevp = prev.lookup(&cpu);
if (prevp) if (prevp)
dist.increment(bpf_log2l(val - *prevp)); dist.increment(bpf_log2l(val - *prevp));
...@@ -34,7 +42,7 @@ int kretprobe__sys_getuid(void *ctx) { ...@@ -34,7 +42,7 @@ int kretprobe__sys_getuid(void *ctx) {
cflags=["-DNUM_CPUS=%d" % multiprocessing.cpu_count()]) cflags=["-DNUM_CPUS=%d" % multiprocessing.cpu_count()])
cnt1 = b["cnt1"] cnt1 = b["cnt1"]
try: try:
cnt1.open_perf_event(cnt1.HW_CPU_CYCLES) cnt1.open_perf_event(bcc.PerfType.HARDWARE, bcc.PerfHWConfig.CPU_CYCLES)
except: except:
if ctypes.get_errno() == 2: if ctypes.get_errno() == 2:
raise self.skipTest("hardware events unsupported") raise self.skipTest("hardware events unsupported")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment