Messages in this thread |  | | From | kan.liang@linux ... | Subject | [PATCH 0/4] bug fix mmap read in large PEBS | Date | Mon, 18 Dec 2017 03:34:47 -0800 |
| |
From: Kan Liang <kan.liang@linux.intel.com>
There is bug when mmap read event->count with large PEBS enabled. Here is an example. #./read_count 0x71f0 0x122c0 0x1000000001c54 0x100000001257d 0x200000000bdc5
The bug is caused by two issues. - In x86_perf_event_update, the calculation of event->count does not take the auto-reload values into account. - In x86_pmu_read, it doesn't count the undrained values in large PEBS buffers.
The issue is introduced with the auto-reload mechanism enabled by commit 851559e35fd5 ("perf/x86/intel: Use the PEBS auto reload mechanism when possible")
The source code of read_count is as below.
struct cpu { int fd; struct perf_event_mmap_page *buf; };
int perf_open(struct cpu *ctx, int cpu) { struct perf_event_attr attr = { .type = PERF_TYPE_HARDWARE, .size = sizeof(struct perf_event_attr), .sample_period = 100000, .config = 0, .sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU, .precise_ip = 3, .mmap = 1, .comm = 1, .task = 1, .mmap2 = 1, .sample_id_all = 1, .comm_exec = 1, }; ctx->buf = NULL; ctx->fd = syscall(__NR_perf_event_open, &attr, -1, cpu, -1, 0); if (ctx->fd < 0) { perror("perf_event_open"); return -1; }
ctx->buf = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ, MAP_SHARED, ctx->fd, 0); if (ctx->buf == MAP_FAILED) { close(ctx->fd); perror("mmap on perf fd"); return -1; } return 0; }
void perf_close(struct cpu *ctx) { close(ctx->fd); if (ctx->buf) munmap(ctx->buf, pagesize); }
int main(int ac, char **av) { struct cpu ctx; u64 count;
perf_open(&ctx, 0);
while (1) { sleep(5);
if (read(ctx.fd, &count, 8) != 8) { perror("counter read"); break; } printf("0x%llx\n", count);
} perf_close(&ctx); }
Kan Liang (4): perf/x86/intel: pass auto-reload information to event update perf/x86/intel: fix event update for auto-reload perf/x86: introduce read function for x86_pmu perf/x86/intel: drain PEBS buffer in event read
arch/x86/events/core.c | 26 ++++++++++++++++++++++---- arch/x86/events/intel/core.c | 18 ++++++++++++++---- arch/x86/events/intel/ds.c | 18 +++++++++++++++++- arch/x86/events/intel/knc.c | 2 +- arch/x86/events/intel/p4.c | 2 +- arch/x86/events/perf_event.h | 9 +++++++-- 6 files changed, 62 insertions(+), 13 deletions(-)
-- 2.7.4
|  |