From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936685AbdLRTrC (ORCPT ); Mon, 18 Dec 2017 14:47:02 -0500 Received: from mga07.intel.com ([134.134.136.100]:37660 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932764AbdLRTq7 (ORCPT ); Mon, 18 Dec 2017 14:46:59 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,423,1508828400"; d="scan'208";a="13375758" From: kan.liang@linux.intel.com To: peterz@infradead.org, mingo@redhat.com, acme@kernel.org, linux-kernel@vger.kernel.org Cc: tglx@linutronix.de, jolsa@redhat.com, eranian@google.com, ak@linux.intel.com, Kan Liang Subject: [PATCH 0/4] bug fix mmap read in large PEBS Date: Mon, 18 Dec 2017 03:34:47 -0800 Message-Id: <1513596891-12362-1-git-send-email-kan.liang@linux.intel.com> X-Mailer: git-send-email 2.7.4 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Kan Liang 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