From patchwork Tue May 24 02:28:59 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Nan X-Patchwork-Id: 68426 Delivered-To: patch@linaro.org Received: by 10.140.92.199 with SMTP id b65csp392000qge; Mon, 23 May 2016 19:30:28 -0700 (PDT) X-Received: by 10.66.242.3 with SMTP id wm3mr2944114pac.81.1464057028367; Mon, 23 May 2016 19:30:28 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 6si1067037paj.187.2016.05.23.19.30.28; Mon, 23 May 2016 19:30:28 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753702AbcEXCaZ (ORCPT + 30 others); Mon, 23 May 2016 22:30:25 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:29597 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752215AbcEXCaX (ORCPT ); Mon, 23 May 2016 22:30:23 -0400 Received: from 172.24.1.47 (EHLO szxeml426-hub.china.huawei.com) ([172.24.1.47]) by szxrg01-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id DKY35815; Tue, 24 May 2016 10:29:18 +0800 (CST) Received: from linux-4hy3.site (10.107.193.248) by szxeml426-hub.china.huawei.com (10.82.67.181) with Microsoft SMTP Server id 14.3.235.1; Tue, 24 May 2016 10:29:11 +0800 From: Wang Nan To: CC: , , Wang Nan , He Kuang , "Arnaldo Carvalho de Melo" , Jiri Olsa , Masami Hiramatsu , Namhyung Kim , "Zefan Li" Subject: [PATCH v4 2/7] perf tools: Don't poll and mmap overwritable events Date: Tue, 24 May 2016 02:28:59 +0000 Message-ID: <1464056944-166978-3-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1464056944-166978-1-git-send-email-wangnan0@huawei.com> References: <1464056944-166978-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.107.193.248] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090203.5743BC81.001E, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 1850354b9d69ffd41fd75483a95adb14 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org There's no need to receive events from overwritable ring buffer. Instead, perf should make them run background until something happen. This patch makes normal events from overwrite events ignored. Overwritable events must be mapped readonly and backward, so if evlist and evsel is not match (evsel->overwrite is true but either evlist is read/write or evlist is not backward, and vice versa), skip mapping it. It is possible that all events in an evlist are overwritable. perf_event__synth_time_conv() should not crash in this case. record__pick_pc() is used to check avaliability. Further commits will expand it when we introduce auxiliary evlists and have multiple mmaps. Signed-off-by: Wang Nan Signed-off-by: He Kuang Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3orama@163.com --- tools/perf/arch/x86/util/tsc.c | 2 ++ tools/perf/builtin-record.c | 9 ++++++++- tools/perf/util/evlist.c | 23 +++++++++++++++++++---- 3 files changed, 29 insertions(+), 5 deletions(-) -- 1.8.3.4 diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c index 357f1b1..2e5567c 100644 --- a/tools/perf/arch/x86/util/tsc.c +++ b/tools/perf/arch/x86/util/tsc.c @@ -62,6 +62,8 @@ int perf_event__synth_time_conv(const struct perf_event_mmap_page *pc, struct perf_tsc_conversion tc; int err; + if (!pc) + return 0; err = perf_read_tsc_conversion(pc, &tc); if (err == -EOPNOTSUPP) return 0; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index dc3fcb5..d4cf1b0 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -655,6 +655,13 @@ perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused return 0; } +static const struct perf_event_mmap_page *record__pick_pc(struct record *rec) +{ + if (rec->evlist && rec->evlist->mmap && rec->evlist->mmap[0].base) + return rec->evlist->mmap[0].base; + return NULL; +} + static int record__synthesize(struct record *rec) { struct perf_session *session = rec->session; @@ -692,7 +699,7 @@ static int record__synthesize(struct record *rec) } } - err = perf_event__synth_time_conv(rec->evlist->mmap[0].base, tool, + err = perf_event__synth_time_conv(record__pick_pc(rec), tool, process_synthesized_event, machine); if (err) goto out; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 55cea69..fbd0d47 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -463,9 +463,9 @@ int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) return 0; } -static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, int idx) +static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, int idx, short revent) { - int pos = fdarray__add(&evlist->pollfd, fd, POLLIN | POLLERR | POLLHUP); + int pos = fdarray__add(&evlist->pollfd, fd, revent | POLLERR | POLLHUP); /* * Save the idx so that when we filter out fds POLLHUP'ed we can * close the associated evlist->mmap[] entry. @@ -481,7 +481,7 @@ static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, int idx int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) { - return __perf_evlist__add_pollfd(evlist, fd, -1); + return __perf_evlist__add_pollfd(evlist, fd, -1, POLLIN); } static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd) @@ -984,15 +984,28 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx, return 0; } +static bool +perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, + struct perf_evsel *evsel) +{ + if (evsel->overwrite) + return false; + return true; +} + static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, struct mmap_params *mp, int cpu, int thread, int *output) { struct perf_evsel *evsel; + int revent; evlist__for_each(evlist->parent, evsel) { int fd; + if (evsel->overwrite != (evlist->overwrite && evlist->backward)) + continue; + if (evsel->system_wide && thread) continue; @@ -1009,6 +1022,8 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, perf_evlist__mmap_get(evlist, idx); } + revent = perf_evlist__should_poll(evlist, evsel) ? POLLIN : 0; + /* * The system_wide flag causes a selected event to be opened * always without a pid. Consequently it will never get a @@ -1017,7 +1032,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, * Therefore don't add it for polling. */ if (!evsel->system_wide && - __perf_evlist__add_pollfd(evlist->parent, fd, idx) < 0) { + __perf_evlist__add_pollfd(evlist->parent, fd, idx, revent) < 0) { perf_evlist__mmap_put(evlist, idx); return -1; }