From 67e4577460f2054cba07eed1d3d89cf3a89c2f6f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 8 Nov 2020 20:10:56 +0100 Subject: [PATCH] 4.4-stable patches added patches: ftrace-fix-recursion-check-for-nmi-test.patch ftrace-handle-tracing-when-switching-between-context.patch --- ...ace-fix-recursion-check-for-nmi-test.patch | 49 ++++++++++ ...acing-when-switching-between-context.patch | 92 +++++++++++++++++++ queue-4.4/series | 2 + 3 files changed, 143 insertions(+) create mode 100644 queue-4.4/ftrace-fix-recursion-check-for-nmi-test.patch create mode 100644 queue-4.4/ftrace-handle-tracing-when-switching-between-context.patch diff --git a/queue-4.4/ftrace-fix-recursion-check-for-nmi-test.patch b/queue-4.4/ftrace-fix-recursion-check-for-nmi-test.patch new file mode 100644 index 00000000000..a96fccf582f --- /dev/null +++ b/queue-4.4/ftrace-fix-recursion-check-for-nmi-test.patch @@ -0,0 +1,49 @@ +From ee11b93f95eabdf8198edd4668bf9102e7248270 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +Date: Thu, 29 Oct 2020 17:31:45 -0400 +Subject: ftrace: Fix recursion check for NMI test + +From: Steven Rostedt (VMware) + +commit ee11b93f95eabdf8198edd4668bf9102e7248270 upstream. + +The code that checks recursion will work to only do the recursion check once +if there's nested checks. The top one will do the check, the other nested +checks will see recursion was already checked and return zero for its "bit". +On the return side, nothing will be done if the "bit" is zero. + +The problem is that zero is returned for the "good" bit when in NMI context. +This will set the bit for NMIs making it look like *all* NMI tracing is +recursing, and prevent tracing of anything in NMI context! + +The simple fix is to return "bit + 1" and subtract that bit on the end to +get the real bit. + +Cc: stable@vger.kernel.org +Fixes: edc15cafcbfa3 ("tracing: Avoid unnecessary multiple recursion checks") +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/kernel/trace/trace.h ++++ b/kernel/trace/trace.h +@@ -529,7 +529,7 @@ static __always_inline int trace_test_an + current->trace_recursion = val; + barrier(); + +- return bit; ++ return bit + 1; + } + + static __always_inline void trace_clear_recursion(int bit) +@@ -539,6 +539,7 @@ static __always_inline void trace_clear_ + if (!bit) + return; + ++ bit--; + bit = 1 << bit; + val &= ~bit; + diff --git a/queue-4.4/ftrace-handle-tracing-when-switching-between-context.patch b/queue-4.4/ftrace-handle-tracing-when-switching-between-context.patch new file mode 100644 index 00000000000..3c7a5015631 --- /dev/null +++ b/queue-4.4/ftrace-handle-tracing-when-switching-between-context.patch @@ -0,0 +1,92 @@ +From 726b3d3f141fba6f841d715fc4d8a4a84f02c02a Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +Date: Thu, 29 Oct 2020 19:35:08 -0400 +Subject: ftrace: Handle tracing when switching between context + +From: Steven Rostedt (VMware) + +commit 726b3d3f141fba6f841d715fc4d8a4a84f02c02a upstream. + +When an interrupt or NMI comes in and switches the context, there's a delay +from when the preempt_count() shows the update. As the preempt_count() is +used to detect recursion having each context have its own bit get set when +tracing starts, and if that bit is already set, it is considered a recursion +and the function exits. But if this happens in that section where context +has changed but preempt_count() has not been updated, this will be +incorrectly flagged as a recursion. + +To handle this case, create another bit call TRANSITION and test it if the +current context bit is already set. Flag the call as a recursion if the +TRANSITION bit is already set, and if not, set it and continue. The +TRANSITION bit will be cleared normally on the return of the function that +set it, or if the current context bit is clear, set it and clear the +TRANSITION bit to allow for another transition between the current context +and an even higher one. + +Cc: stable@vger.kernel.org +Fixes: edc15cafcbfa3 ("tracing: Avoid unnecessary multiple recursion checks") +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace.h | 23 +++++++++++++++++++++-- + kernel/trace/trace_selftest.c | 9 +++++++-- + 2 files changed, 28 insertions(+), 4 deletions(-) + +--- a/kernel/trace/trace.h ++++ b/kernel/trace/trace.h +@@ -478,6 +478,12 @@ enum { + * can only be modified by current, we can reuse trace_recursion. + */ + TRACE_IRQ_BIT, ++ ++ /* ++ * When transitioning between context, the preempt_count() may ++ * not be correct. Allow for a single recursion to cover this case. ++ */ ++ TRACE_TRANSITION_BIT, + }; + + #define trace_recursion_set(bit) do { (current)->trace_recursion |= (1<<(bit)); } while (0) +@@ -522,8 +528,21 @@ static __always_inline int trace_test_an + return 0; + + bit = trace_get_context_bit() + start; +- if (unlikely(val & (1 << bit))) +- return -1; ++ if (unlikely(val & (1 << bit))) { ++ /* ++ * It could be that preempt_count has not been updated during ++ * a switch between contexts. Allow for a single recursion. ++ */ ++ bit = TRACE_TRANSITION_BIT; ++ if (trace_recursion_test(bit)) ++ return -1; ++ trace_recursion_set(bit); ++ barrier(); ++ return bit + 1; ++ } ++ ++ /* Normal check passed, clear the transition to allow it again */ ++ trace_recursion_clear(TRACE_TRANSITION_BIT); + + val |= 1 << bit; + current->trace_recursion = val; +--- a/kernel/trace/trace_selftest.c ++++ b/kernel/trace/trace_selftest.c +@@ -490,8 +490,13 @@ trace_selftest_function_recursion(void) + unregister_ftrace_function(&test_rec_probe); + + ret = -1; +- if (trace_selftest_recursion_cnt != 1) { +- pr_cont("*callback not called once (%d)* ", ++ /* ++ * Recursion allows for transitions between context, ++ * and may call the callback twice. ++ */ ++ if (trace_selftest_recursion_cnt != 1 && ++ trace_selftest_recursion_cnt != 2) { ++ pr_cont("*callback not called once (or twice) (%d)* ", + trace_selftest_recursion_cnt); + goto out; + } diff --git a/queue-4.4/series b/queue-4.4/series index b4a8a8a6359..4b9377d7e36 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -67,3 +67,5 @@ gianfar-replace-skb_realloc_headroom-with-skb_cow_head-for-ptp.patch gianfar-account-for-tx-ptp-timestamp-in-the-skb-headroom.patch fonts-replace-discarded-const-qualifier.patch alsa-usb-audio-add-implicit-feedback-quirk-for-qu-16.patch +ftrace-fix-recursion-check-for-nmi-test.patch +ftrace-handle-tracing-when-switching-between-context.patch -- 2.47.3