From patchwork Mon Sep 5 16:31:31 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Punit Agrawal X-Patchwork-Id: 9314319 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 0053D60869 for ; Mon, 5 Sep 2016 16:34:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E745128B04 for ; Mon, 5 Sep 2016 16:34:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D99B428B01; Mon, 5 Sep 2016 16:34:28 +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 5295228AF9 for ; Mon, 5 Sep 2016 16:34:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933488AbcIEQci (ORCPT ); Mon, 5 Sep 2016 12:32:38 -0400 Received: from fw-tnat.cambridge.arm.com ([217.140.96.140]:28893 "EHLO cam-smtp0.cambridge.arm.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932301AbcIEQcg (ORCPT ); Mon, 5 Sep 2016 12:32:36 -0400 Received: from e105922-lin.cambridge.arm.com (e105922-lin.cambridge.arm.com [10.1.194.52]) by cam-smtp0.cambridge.arm.com (8.13.8/8.13.8) with SMTP id u85GW2TK008725; Mon, 5 Sep 2016 17:32:03 +0100 Received: by e105922-lin.cambridge.arm.com (sSMTP sendmail emulation); Mon, 05 Sep 2016 17:32:02 +0100 From: Punit Agrawal To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Cc: Punit Agrawal , Christoffer Dall , Marc Zyngier , Steven Rostedt , Ingo Molnar , Will Deacon Subject: [RFC v2 PATCH 1/7] perf/trace: Add notification for perf trace events Date: Mon, 5 Sep 2016 17:31:31 +0100 Message-Id: <1473093097-30932-2-git-send-email-punit.agrawal@arm.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1473093097-30932-1-git-send-email-punit.agrawal@arm.com> References: <1473093097-30932-1-git-send-email-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 --- 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 @@ out: 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,