From patchwork Wed Oct 26 17:41:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Punit Agrawal X-Patchwork-Id: 9397959 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 69F6960477 for ; Wed, 26 Oct 2016 17:45:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F216B29BD2 for ; Wed, 26 Oct 2016 17:45:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D85DF29BCC; Wed, 26 Oct 2016 17:45:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 00BDC29BCC for ; Wed, 26 Oct 2016 17:45:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933565AbcJZRpM (ORCPT ); Wed, 26 Oct 2016 13:45:12 -0400 Received: from foss.arm.com ([217.140.101.70]:48434 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756293AbcJZRm3 (ORCPT ); Wed, 26 Oct 2016 13:42:29 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id AE54516; Wed, 26 Oct 2016 10:42:28 -0700 (PDT) Received: from localhost (e105922-lin.cambridge.arm.com [10.1.195.25]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 7F80F3F487; Wed, 26 Oct 2016 10:42:28 -0700 (PDT) From: Punit Agrawal To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Steven Rostedt , Ingo Molnar , Jiri Olsa Cc: Punit Agrawal , Christoffer Dall , Marc Zyngier , Will Deacon Subject: [PATCH v2 3/8] perf/trace: Add notification for perf trace events Date: Wed, 26 Oct 2016 18:41:43 +0100 Message-Id: <20161026174148.17172-4-punit.agrawal@arm.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20161026174148.17172-1-punit.agrawal@arm.com> References: <20161026174148.17172-1-punit.agrawal@arm.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a mechanism to notify listeners about perf trace event state changes. This enables listeners to take actions requiring the event context (e.g., attached process). The notification mechanism can be used to reduce trace point based profiling overhead by enabling/disabling hardware traps for specific contexts (e.g., virtual machines). Signed-off-by: Punit Agrawal Cc: Steven Rostedt Cc: Ingo Molnar Cc: Jiri Olsa --- include/linux/trace_events.h | 3 +++ kernel/trace/trace_event_perf.c | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index be00761..5924032 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -505,6 +505,9 @@ perf_trace_buf_submit(void *raw_data, int size, int rctx, u16 type, { perf_tp_event(type, count, raw_data, size, regs, head, rctx, task); } + +extern int perf_trace_notifier_register(struct notifier_block *nb); +extern int perf_trace_notifier_unregister(struct notifier_block *nb); #endif #endif /* _LINUX_TRACE_EVENT_H */ diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 562fa69..9aaaacf 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c @@ -6,10 +6,12 @@ */ #include +#include #include #include "trace.h" static char __percpu *perf_trace_buf[PERF_NR_CONTEXTS]; +static RAW_NOTIFIER_HEAD(perf_trace_notifier_list); /* * Force it to be aligned to unsigned long to avoid misaligned accesses @@ -86,6 +88,26 @@ static int perf_trace_event_perm(struct trace_event_call *tp_event, return 0; } +int perf_trace_notifier_register(struct notifier_block *nb) +{ + return raw_notifier_chain_register(&perf_trace_notifier_list, nb); +} + +int perf_trace_notifier_unregister(struct notifier_block *nb) +{ + return raw_notifier_chain_unregister(&perf_trace_notifier_list, nb); +} + +static void perf_trace_notify(enum trace_reg event, struct perf_event *p_event) +{ + /* + * We use raw notifiers here as we are called with the + * event_mutex held. + */ + raw_notifier_call_chain(&perf_trace_notifier_list, + event, p_event); +} + static int perf_trace_event_reg(struct trace_event_call *tp_event, struct perf_event *p_event) { @@ -176,6 +198,7 @@ static void perf_trace_event_unreg(struct perf_event *p_event) static int perf_trace_event_open(struct perf_event *p_event) { struct trace_event_call *tp_event = p_event->tp_event; + perf_trace_notify(TRACE_REG_PERF_OPEN, p_event); return tp_event->class->reg(tp_event, TRACE_REG_PERF_OPEN, p_event); } @@ -183,6 +206,7 @@ static void perf_trace_event_close(struct perf_event *p_event) { struct trace_event_call *tp_event = p_event->tp_event; tp_event->class->reg(tp_event, TRACE_REG_PERF_CLOSE, p_event); + perf_trace_notify(TRACE_REG_PERF_CLOSE, p_event); } static int perf_trace_event_init(struct trace_event_call *tp_event,