From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753057AbbBZEPG (ORCPT ); Wed, 25 Feb 2015 23:15:06 -0500 Received: from terminus.zytor.com ([198.137.202.10]:48729 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752954AbbBZEPC (ORCPT ); Wed, 25 Feb 2015 23:15:02 -0500 Date: Wed, 25 Feb 2015 20:14:20 -0800 From: tip-bot for Matt Fleming Message-ID: Cc: kanaka.d.juvva@intel.com, linux-kernel@vger.kernel.org, jolsa@redhat.com, acme@kernel.org, matt.fleming@intel.com, torvalds@linux-foundation.org, vikas.shivappa@linux.intel.com, acme@redhat.com, tglx@linutronix.de, mingo@kernel.org, hpa@zytor.com, peterz@infradead.org Reply-To: hpa@zytor.com, peterz@infradead.org, torvalds@linux-foundation.org, mingo@kernel.org, vikas.shivappa@linux.intel.com, tglx@linutronix.de, acme@redhat.com, acme@kernel.org, matt.fleming@intel.com, linux-kernel@vger.kernel.org, jolsa@redhat.com, kanaka.d.juvva@intel.com In-Reply-To: <1422038748-21397-3-git-send-email-matt@codeblueprint.co.uk> References: <1422038748-21397-3-git-send-email-matt@codeblueprint.co.uk> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/x86] perf: Add ->count() function to read per-package counters Git-Commit-ID: eacd3ecc34472ce3751eedfc94e44c7cc6eb6305 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: eacd3ecc34472ce3751eedfc94e44c7cc6eb6305 Gitweb: http://git.kernel.org/tip/eacd3ecc34472ce3751eedfc94e44c7cc6eb6305 Author: Matt Fleming AuthorDate: Fri, 23 Jan 2015 18:45:41 +0000 Committer: Ingo Molnar CommitDate: Wed, 25 Feb 2015 13:53:29 +0100 perf: Add ->count() function to read per-package counters For PMU drivers that record per-package counters, the ->count variable cannot be used to record an accurate aggregated value, since it's not possible to perform SMP cross-calls to cpus on other packages from the context in which we update ->count. Introduce a new optional ->count() accessor function that can be used to customize how values are collected. If a PMU driver doesn't provide a ->count() function, we fallback to the existing code. There is necessarily a window of staleness with this approach because the task that generated the counter value may not have been scheduled by the cpu recently. An alternative and more complex approach would be to use a hrtimer to periodically refresh the values from a more permissive scheduling context. So, we're trading off complexity for accuracy. Signed-off-by: Matt Fleming Signed-off-by: Peter Zijlstra (Intel) Cc: Arnaldo Carvalho de Melo Cc: Arnaldo Carvalho de Melo Cc: H. Peter Anvin Cc: Jiri Olsa Cc: Kanaka Juvva Cc: Linus Torvalds Cc: Vikas Shivappa Link: http://lkml.kernel.org/r/1422038748-21397-3-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- include/linux/perf_event.h | 10 ++++++++++ kernel/events/core.c | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index cae4a94..9fc9b0d 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -272,6 +272,11 @@ struct pmu { */ size_t task_ctx_size; + + /* + * Return the count value for a counter. + */ + u64 (*count) (struct perf_event *event); /*optional*/ }; /** @@ -770,6 +775,11 @@ static inline void perf_event_task_sched_out(struct task_struct *prev, __perf_event_task_sched_out(prev, next); } +static inline u64 __perf_event_count(struct perf_event *event) +{ + return local64_read(&event->count) + atomic64_read(&event->child_count); +} + extern void perf_event_mmap(struct vm_area_struct *vma); extern struct perf_guest_info_callbacks *perf_guest_cbs; extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks); diff --git a/kernel/events/core.c b/kernel/events/core.c index 072de31..4e8dc59 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -3194,7 +3194,10 @@ static void __perf_event_read(void *info) static inline u64 perf_event_count(struct perf_event *event) { - return local64_read(&event->count) + atomic64_read(&event->child_count); + if (event->pmu->count) + return event->pmu->count(event); + + return __perf_event_count(event); } static u64 perf_event_read(struct perf_event *event)