From patchwork Thu Feb 18 22:21:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Jeanson X-Patchwork-Id: 12094413 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A6128C433DB for ; Thu, 18 Feb 2021 22:22:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5B5AA64EBD for ; Thu, 18 Feb 2021 22:22:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230154AbhBRWW0 (ORCPT ); Thu, 18 Feb 2021 17:22:26 -0500 Received: from mail.efficios.com ([167.114.26.124]:43634 "EHLO mail.efficios.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229994AbhBRWWX (ORCPT ); Thu, 18 Feb 2021 17:22:23 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.efficios.com (Postfix) with ESMTP id 7EE3D29EB6B; Thu, 18 Feb 2021 17:21:41 -0500 (EST) Received: from mail.efficios.com ([127.0.0.1]) by localhost (mail03.efficios.com [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id 0sxkd1Q1z6-t; Thu, 18 Feb 2021 17:21:41 -0500 (EST) Received: from localhost (localhost [127.0.0.1]) by mail.efficios.com (Postfix) with ESMTP id 0CC5E29EBC8; Thu, 18 Feb 2021 17:21:41 -0500 (EST) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.efficios.com 0CC5E29EBC8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=efficios.com; s=default; t=1613686901; bh=b/tImsiFHKIA83RvVBBtFOlZLElt7JWgzez3MFpncDY=; h=From:To:Date:Message-Id:MIME-Version; b=ismR514jxZdPkPLo4uxcO5/QVSxqyQkjgJ/gU6MQ1LsFj1dMC/a+B5QehiYZWem10 sacwDd/mti6/oPMZyNVDYC0oLYHshG0ZlCh6V4Ib4Bdy7nerOAccrX9/awcK86LCpK fVALhtZB88c4pECEk4TvtLEB2qHMpmFeGJ8PC72QsQTuoCqEPkOfZbwejsDZPJSk9d cgbAsIYv1+zjviliD/+prgBJkZB4k946VAFeIVexpo+eSyQyhIldEViTQ7biTceNWZ dv/bkoNhoWLEkaf9AdHtnxgactDLhzxMFFXXzYlL1OqsqUmi0tSILH3qk+wmxT4YiR 3WE2MK+LmJ5LA== X-Virus-Scanned: amavisd-new at efficios.com Received: from mail.efficios.com ([127.0.0.1]) by localhost (mail03.efficios.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id n6Fu7MKTR4v4; Thu, 18 Feb 2021 17:21:40 -0500 (EST) Received: from localhost.localdomain (96-127-212-112.qc.cable.ebox.net [96.127.212.112]) by mail.efficios.com (Postfix) with ESMTPSA id AF6A829EE91; Thu, 18 Feb 2021 17:21:40 -0500 (EST) From: Michael Jeanson To: linux-kernel@vger.kernel.org Cc: Michael Jeanson , Mathieu Desnoyers , Steven Rostedt , Peter Zijlstra , Alexei Starovoitov , Yonghong Song , "Paul E . McKenney" , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , bpf@vger.kernel.org, Joel Fernandes Subject: [RFC PATCH 2/6] tracing: ftrace: add support for faultable tracepoints Date: Thu, 18 Feb 2021 17:21:21 -0500 Message-Id: <20210218222125.46565-3-mjeanson@efficios.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210218222125.46565-1-mjeanson@efficios.com> References: <20210218222125.46565-1-mjeanson@efficios.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-State: RFC In preparation for converting system call enter/exit instrumentation into faultable tracepoints, make sure that ftrace can handle registering to such tracepoints by explicitly disabling preemption within the ftrace tracepoint probes to respect the current expectations within ftrace ring buffer code. This change does not yet allow ftrace to take page faults per se within its probe, but allows its existing probes to connect to faultable tracepoints. Co-developed-by: Mathieu Desnoyers Signed-off-by: Mathieu Desnoyers Signed-off-by: Michael Jeanson Cc: Steven Rostedt (VMware) Cc: Peter Zijlstra Cc: Alexei Starovoitov Cc: Yonghong Song Cc: Paul E. McKenney Cc: Ingo Molnar Cc: Arnaldo Carvalho de Melo Cc: Mark Rutland Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Namhyung Kim Cc: bpf@vger.kernel.org Cc: Joel Fernandes --- include/trace/trace_events.h | 75 +++++++++++++++++++++++++++++++++--- kernel/trace/trace_events.c | 15 +++++++- 2 files changed, 83 insertions(+), 7 deletions(-) diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h index af9807251226..5125d3fcf963 100644 --- a/include/trace/trace_events.h +++ b/include/trace/trace_events.h @@ -80,6 +80,16 @@ TRACE_MAKE_SYSTEM_STR(); PARAMS(print)); \ DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args)); +#undef TRACE_EVENT_MAYFAULT +#define TRACE_EVENT_MAYFAULT(name, proto, args, tstruct, assign, print) \ + DECLARE_EVENT_CLASS_MAYFAULT(name, \ + PARAMS(proto), \ + PARAMS(args), \ + PARAMS(tstruct), \ + PARAMS(assign), \ + PARAMS(print)); \ + DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args)); + #undef __field #define __field(type, item) type item; @@ -118,6 +128,12 @@ TRACE_MAKE_SYSTEM_STR(); \ static struct trace_event_class event_class_##name; +#undef DECLARE_EVENT_CLASS_MAYFAULT +#define DECLARE_EVENT_CLASS_MAYFAULT(name, proto, args, \ + tstruct, assign, print) \ + DECLARE_EVENT_CLASS(name, PARAMS(proto), PARAMS(args), \ + PARAMS(tstruct), PARAMS(assign), PARAMS(print)) + #undef DEFINE_EVENT #define DEFINE_EVENT(template, name, proto, args) \ static struct trace_event_call __used \ @@ -141,7 +157,7 @@ TRACE_MAKE_SYSTEM_STR(); #undef TRACE_EVENT_FN_MAYFAULT #define TRACE_EVENT_FN_MAYFAULT(name, proto, args, tstruct, \ assign, print, reg, unreg) \ - TRACE_EVENT(name, PARAMS(proto), PARAMS(args), \ + TRACE_EVENT_MAYFAULT(name, PARAMS(proto), PARAMS(args), \ PARAMS(tstruct), PARAMS(assign), PARAMS(print)) \ #undef TRACE_EVENT_FN_COND @@ -212,6 +228,12 @@ TRACE_MAKE_SYSTEM_STR(); tstruct; \ }; +#undef DECLARE_EVENT_CLASS_MAYFAULT +#define DECLARE_EVENT_CLASS_MAYFAULT(call, proto, args, \ + tstruct, assign, print) \ + DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), \ + PARAMS(tstruct), PARAMS(assign), PARAMS(print)) + #undef DEFINE_EVENT #define DEFINE_EVENT(template, name, proto, args) @@ -378,6 +400,12 @@ static struct trace_event_functions trace_event_type_funcs_##call = { \ .trace = trace_raw_output_##call, \ }; +#undef DECLARE_EVENT_CLASS_MAYFAULT +#define DECLARE_EVENT_CLASS_MAYFAULT(call, proto, args, \ + tstruct, assign, print) \ + DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), \ + PARAMS(tstruct), PARAMS(assign), PARAMS(print)) + #undef DEFINE_EVENT_PRINT #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ static notrace enum print_line_t \ @@ -448,6 +476,12 @@ static struct trace_event_fields trace_event_fields_##call[] = { \ tstruct \ {} }; +#undef DECLARE_EVENT_CLASS_MAYFAULT +#define DECLARE_EVENT_CLASS_MAYFAULT(call, proto, args, \ + tstruct, func, print) \ + DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), \ + PARAMS(tstruct), PARAMS(func), PARAMS(print)) + #undef DEFINE_EVENT_PRINT #define DEFINE_EVENT_PRINT(template, name, proto, args, print) @@ -524,6 +558,12 @@ static inline notrace int trace_event_get_offsets_##call( \ return __data_size; \ } +#undef DECLARE_EVENT_CLASS_MAYFAULT +#define DECLARE_EVENT_CLASS_MAYFAULT(call, proto, args, \ + tstruct, assign, print) \ + DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), \ + PARAMS(tstruct), PARAMS(assign), PARAMS(print)) + #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) /* @@ -673,8 +713,8 @@ static inline notrace int trace_event_get_offsets_##call( \ #undef __perf_task #define __perf_task(t) (t) -#undef DECLARE_EVENT_CLASS -#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ +#undef _DECLARE_EVENT_CLASS +#define _DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print, tp_flags) \ \ static notrace void \ trace_event_raw_event_##call(void *__data, proto) \ @@ -685,8 +725,11 @@ trace_event_raw_event_##call(void *__data, proto) \ struct trace_event_raw_##call *entry; \ int __data_size; \ \ + if ((tp_flags) & TRACEPOINT_MAYFAULT) \ + preempt_disable_notrace(); \ + \ if (trace_trigger_soft_disabled(trace_file)) \ - return; \ + goto end; \ \ __data_size = trace_event_get_offsets_##call(&__data_offsets, args); \ \ @@ -694,14 +737,30 @@ trace_event_raw_event_##call(void *__data, proto) \ sizeof(*entry) + __data_size); \ \ if (!entry) \ - return; \ + goto end; \ \ tstruct \ \ { assign; } \ \ trace_event_buffer_commit(&fbuffer); \ +end: \ + if ((tp_flags) & TRACEPOINT_MAYFAULT) \ + preempt_enable_notrace(); \ } + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ + _DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), \ + PARAMS(tstruct), PARAMS(assign), \ + PARAMS(print), 0) + +#undef DECLARE_EVENT_CLASS_MAYFAULT +#define DECLARE_EVENT_CLASS_MAYFAULT(call, proto, args, tstruct, assign, print) \ + _DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), \ + PARAMS(tstruct), PARAMS(assign), \ + PARAMS(print), TRACEPOINT_MAYFAULT) + /* * The ftrace_test_probe is compiled out, it is only here as a build time check * to make sure that if the tracepoint handling changes, the ftrace probe will @@ -748,6 +807,12 @@ static struct trace_event_class __used __refdata event_class_##call = { \ _TRACE_PERF_INIT(call) \ }; +#undef DECLARE_EVENT_CLASS_MAYFAULT +#define DECLARE_EVENT_CLASS_MAYFAULT(call, proto, args, \ + tstruct, assign, print) \ + DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), \ + PARAMS(tstruct), PARAMS(assign), PARAMS(print)) + #undef DEFINE_EVENT #define DEFINE_EVENT(template, call, proto, args) \ \ diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 802f3e7d8b8b..ed2ca828311a 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -291,9 +291,15 @@ int trace_event_reg(struct trace_event_call *call, WARN_ON(!(call->flags & TRACE_EVENT_FL_TRACEPOINT)); switch (type) { case TRACE_REG_REGISTER: - return tracepoint_probe_register(call->tp, + if (call->tp->flags & TRACEPOINT_MAYFAULT) + return tracepoint_probe_register_mayfault(call->tp, call->class->probe, file); + else + return tracepoint_probe_register(call->tp, + call->class->probe, + file); + case TRACE_REG_UNREGISTER: tracepoint_probe_unregister(call->tp, call->class->probe, @@ -302,7 +308,12 @@ int trace_event_reg(struct trace_event_call *call, #ifdef CONFIG_PERF_EVENTS case TRACE_REG_PERF_REGISTER: - return tracepoint_probe_register(call->tp, + if (call->tp->flags & TRACEPOINT_MAYFAULT) + return tracepoint_probe_register_mayfault(call->tp, + call->class->perf_probe, + call); + else + return tracepoint_probe_register(call->tp, call->class->perf_probe, call); case TRACE_REG_PERF_UNREGISTER: