Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp2498983imm; Thu, 9 Aug 2018 14:08:18 -0700 (PDT) X-Google-Smtp-Source: AA+uWPwWmqAdgJb/IYn2QPgl/CqMUiK5E+PKfT+xLyJu4dNTV8y4qM5VpECo850E4mVbXJ2aFxcN X-Received: by 2002:a17:902:246a:: with SMTP id m39-v6mr3408853plg.57.1533848898407; Thu, 09 Aug 2018 14:08:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533848898; cv=none; d=google.com; s=arc-20160816; b=X7TqblRvtg6sKwFwPiyj2uHQSN1h7+6l2jgEj3HtAB8Rnq3Yh+KQjxfBA+SPQkxsXC U7z1KOtnKFRbUe1vFgAHuPV6dvm1KCl4lPyHlSDU0GkmoC6Zqj97z45zVIB7u/yHt1Bw siFdcQuoi25ZZw0NzUfgfTdtTG1tKPdDUfzw9yb4A/sE0/y1lTQ4VMtPlZFSITbxOgCs Xf3DTA4V9xSfdHB9qRM3QIVY9wD1Z8QwTxbKUoGqgrsDBb/bSsMBaT/9EGGcXq6fz2Bh W4n5kVfUssKM6j+6BaQeYGuegdSan6EcND+AR004M81UFnu5B3jryDdBwsrf8L18oDD6 jthg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:subject:cc:to :from:date:user-agent:message-id:arc-authentication-results; bh=o8tJUgnxE9nVTPFOA+kfEXpjYVx4+Y773FHBO6AeFlM=; b=E0GrHnJM09GCObhkDuMJRhPF+Sxyv557HbZz/fdaGqWv6EMVrLN4M9inZKycCOIsVY 3SsK7RA16PbSuf2KKrMQjvoStuVyR6/JtaSLtlbLSzBSSZfwcB/pEsocnJ8d2hw5X+c1 6L8LaIsA28jM1B0lSorkXyVeoADynoy2In5KjrAZn/xgj0cy2lRVKwu/EJ8SdIl6hUwM UVV69vks1MtIWq9IeqbvjxyJHht5vBq53mxAn50QVZs76mdh74RaruebXZ5ksq9wuXNg h0DHbm9VNFs4K19N4cG/X7PvCeYADx4wFwe6YF8bByglp9usjyXQGUcF5kLVTheGu5qu fssA== ARC-Authentication-Results: i=1; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id bi1-v6si6554570plb.399.2018.08.09.14.08.03; Thu, 09 Aug 2018 14:08:18 -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 S1727502AbeHIXdl (ORCPT + 99 others); Thu, 9 Aug 2018 19:33:41 -0400 Received: from mail.kernel.org ([198.145.29.99]:35724 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727319AbeHIXdd (ORCPT ); Thu, 9 Aug 2018 19:33:33 -0400 Received: from gandalf.local.home (cpe-66-24-56-78.stny.res.rr.com [66.24.56.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E89E322392; Thu, 9 Aug 2018 21:06:55 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.91) (envelope-from ) id 1fns90-0001RU-NN; Thu, 09 Aug 2018 17:06:54 -0400 Message-Id: <20180809210654.622445925@goodmis.org> User-Agent: quilt/0.65 Date: Thu, 09 Aug 2018 17:03:36 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Ingo Molnar , Andrew Morton , joel@joelfernandes.org, Joel Fernandes Subject: [for-next][PATCH 3/6] tracing: More reverting of "tracing: Centralize preemptirq tracepoints and unify their usage" References: <20180809210333.588854137@goodmis.org> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "Steven Rostedt (VMware)" Joel Fernandes created a nice patch that cleaned up the duplicate hooks used by lockdep and irqsoff latency tracer. It made both use tracepoints. But the latency tracer is triggering warnings when using tracepoints to call into the latency tracer's routines. Mainly, they can be called from NMI context. If that happens, then the SRCU may not work properly because on some architectures, SRCU is not safe to be called in both NMI and non-NMI context. This is a partial revert of the clean up patch c3bc8fd637a9 ("tracing: Centralize preemptirq tracepoints and unify their usage") that adds back the direct calls into the latency tracer. It also only calls the trace events when not in NMI. Cc: Joel Fernandes Fixes: c3bc8fd637a9 ("tracing: Centralize preemptirq tracepoints and unify their usage") Signed-off-by: Steven Rostedt (VMware) --- kernel/trace/trace.h | 15 +++++++++++ kernel/trace/trace_irqsoff.c | 48 +++------------------------------ kernel/trace/trace_preemptirq.c | 25 ++++++++++++----- 3 files changed, 38 insertions(+), 50 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index d88cd9bb72f4..a62b678731e3 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -1827,6 +1827,21 @@ static inline int tracing_alloc_snapshot_instance(struct trace_array *tr) } #endif +#ifdef CONFIG_PREEMPT_TRACER +void tracer_preempt_on(unsigned long a0, unsigned long a1); +void tracer_preempt_off(unsigned long a0, unsigned long a1); +#else +static inline void tracer_preempt_on(unsigned long a0, unsigned long a1) { } +static inline void tracer_preempt_off(unsigned long a0, unsigned long a1) { } +#endif +#ifdef CONFIG_IRQSOFF_TRACER +void tracer_hardirqs_on(unsigned long a0, unsigned long a1); +void tracer_hardirqs_off(unsigned long a0, unsigned long a1); +#else +static inline void tracer_hardirqs_on(unsigned long a0, unsigned long a1) { } +static inline void tracer_hardirqs_off(unsigned long a0, unsigned long a1) { } +#endif + extern struct trace_iterator *tracepoint_print_iter; #endif /* _LINUX_KERNEL_TRACE_H */ diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 4af990e9c594..94c1ba139b3b 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -605,40 +605,18 @@ static void irqsoff_tracer_stop(struct trace_array *tr) /* * We are only interested in hardirq on/off events: */ -static void tracer_hardirqs_on(void *none, unsigned long a0, unsigned long a1) +void tracer_hardirqs_on(unsigned long a0, unsigned long a1) { unsigned int pc = preempt_count(); - /* - * Tracepoint probes are expected to be called with preempt disabled, - * We don't care about being called with preempt disabled but we need - * to know in the future if that changes so we can remove the next - * preempt_enable. - */ - WARN_ON_ONCE(pc < PREEMPT_DISABLE_OFFSET); - - /* Use PREEMPT_DISABLE_OFFSET to handle !CONFIG_PREEMPT cases */ - pc -= PREEMPT_DISABLE_OFFSET; - if (!preempt_trace(pc) && irq_trace()) stop_critical_timing(a0, a1, pc); } -static void tracer_hardirqs_off(void *none, unsigned long a0, unsigned long a1) +void tracer_hardirqs_off(unsigned long a0, unsigned long a1) { unsigned int pc = preempt_count(); - /* - * Tracepoint probes are expected to be called with preempt disabled, - * We don't care about being called with preempt disabled but we need - * to know in the future if that changes so we can remove the next - * preempt_enable. - */ - WARN_ON_ONCE(pc < PREEMPT_DISABLE_OFFSET); - - /* Use PREEMPT_DISABLE_OFFSET to handle !CONFIG_PREEMPT cases */ - pc -= PREEMPT_DISABLE_OFFSET; - if (!preempt_trace(pc) && irq_trace()) start_critical_timing(a0, a1, pc); } @@ -647,15 +625,11 @@ static int irqsoff_tracer_init(struct trace_array *tr) { trace_type = TRACER_IRQS_OFF; - register_trace_irq_disable(tracer_hardirqs_off, NULL); - register_trace_irq_enable(tracer_hardirqs_on, NULL); return __irqsoff_tracer_init(tr); } static void irqsoff_tracer_reset(struct trace_array *tr) { - unregister_trace_irq_disable(tracer_hardirqs_off, NULL); - unregister_trace_irq_enable(tracer_hardirqs_on, NULL); __irqsoff_tracer_reset(tr); } @@ -681,7 +655,7 @@ static struct tracer irqsoff_tracer __read_mostly = #endif /* CONFIG_IRQSOFF_TRACER */ #ifdef CONFIG_PREEMPT_TRACER -static void tracer_preempt_on(void *none, unsigned long a0, unsigned long a1) +void tracer_preempt_on(unsigned long a0, unsigned long a1) { int pc = preempt_count(); @@ -689,7 +663,7 @@ static void tracer_preempt_on(void *none, unsigned long a0, unsigned long a1) stop_critical_timing(a0, a1, pc); } -static void tracer_preempt_off(void *none, unsigned long a0, unsigned long a1) +void tracer_preempt_off(unsigned long a0, unsigned long a1) { int pc = preempt_count(); @@ -701,15 +675,11 @@ static int preemptoff_tracer_init(struct trace_array *tr) { trace_type = TRACER_PREEMPT_OFF; - register_trace_preempt_disable(tracer_preempt_off, NULL); - register_trace_preempt_enable(tracer_preempt_on, NULL); return __irqsoff_tracer_init(tr); } static void preemptoff_tracer_reset(struct trace_array *tr) { - unregister_trace_preempt_disable(tracer_preempt_off, NULL); - unregister_trace_preempt_enable(tracer_preempt_on, NULL); __irqsoff_tracer_reset(tr); } @@ -740,21 +710,11 @@ static int preemptirqsoff_tracer_init(struct trace_array *tr) { trace_type = TRACER_IRQS_OFF | TRACER_PREEMPT_OFF; - register_trace_irq_disable(tracer_hardirqs_off, NULL); - register_trace_irq_enable(tracer_hardirqs_on, NULL); - register_trace_preempt_disable(tracer_preempt_off, NULL); - register_trace_preempt_enable(tracer_preempt_on, NULL); - return __irqsoff_tracer_init(tr); } static void preemptirqsoff_tracer_reset(struct trace_array *tr) { - unregister_trace_irq_disable(tracer_hardirqs_off, NULL); - unregister_trace_irq_enable(tracer_hardirqs_on, NULL); - unregister_trace_preempt_disable(tracer_preempt_off, NULL); - unregister_trace_preempt_enable(tracer_preempt_on, NULL); - __irqsoff_tracer_reset(tr); } diff --git a/kernel/trace/trace_preemptirq.c b/kernel/trace/trace_preemptirq.c index fa656b25f427..71f553cceb3c 100644 --- a/kernel/trace/trace_preemptirq.c +++ b/kernel/trace/trace_preemptirq.c @@ -9,6 +9,7 @@ #include #include #include +#include "trace.h" #define CREATE_TRACE_POINTS #include @@ -20,7 +21,9 @@ static DEFINE_PER_CPU(int, tracing_irq_cpu); void trace_hardirqs_on(void) { if (this_cpu_read(tracing_irq_cpu)) { - trace_irq_enable_rcuidle(CALLER_ADDR0, CALLER_ADDR1); + if (!in_nmi()) + trace_irq_enable_rcuidle(CALLER_ADDR0, CALLER_ADDR1); + tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1); this_cpu_write(tracing_irq_cpu, 0); } @@ -32,7 +35,9 @@ void trace_hardirqs_off(void) { if (!this_cpu_read(tracing_irq_cpu)) { this_cpu_write(tracing_irq_cpu, 1); - trace_irq_disable_rcuidle(CALLER_ADDR0, CALLER_ADDR1); + tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1); + if (!in_nmi()) + trace_irq_disable_rcuidle(CALLER_ADDR0, CALLER_ADDR1); } lockdep_hardirqs_off(CALLER_ADDR0); @@ -42,7 +47,9 @@ EXPORT_SYMBOL(trace_hardirqs_off); __visible void trace_hardirqs_on_caller(unsigned long caller_addr) { if (this_cpu_read(tracing_irq_cpu)) { - trace_irq_enable_rcuidle(CALLER_ADDR0, caller_addr); + if (!in_nmi()) + trace_irq_enable_rcuidle(CALLER_ADDR0, caller_addr); + tracer_hardirqs_on(CALLER_ADDR0, caller_addr); this_cpu_write(tracing_irq_cpu, 0); } @@ -54,7 +61,9 @@ __visible void trace_hardirqs_off_caller(unsigned long caller_addr) { if (!this_cpu_read(tracing_irq_cpu)) { this_cpu_write(tracing_irq_cpu, 1); - trace_irq_disable_rcuidle(CALLER_ADDR0, caller_addr); + tracer_hardirqs_off(CALLER_ADDR0, caller_addr); + if (!in_nmi()) + trace_irq_disable_rcuidle(CALLER_ADDR0, caller_addr); } lockdep_hardirqs_off(CALLER_ADDR0); @@ -66,11 +75,15 @@ EXPORT_SYMBOL(trace_hardirqs_off_caller); void trace_preempt_on(unsigned long a0, unsigned long a1) { - trace_preempt_enable_rcuidle(a0, a1); + if (!in_nmi()) + trace_preempt_enable_rcuidle(a0, a1); + tracer_preempt_on(a0, a1); } void trace_preempt_off(unsigned long a0, unsigned long a1) { - trace_preempt_disable_rcuidle(a0, a1); + if (!in_nmi()) + trace_preempt_disable_rcuidle(a0, a1); + tracer_preempt_off(a0, a1); } #endif -- 2.18.0