Messages in this thread Patch in this message | | | Date | Wed, 28 Oct 2020 07:52:47 -0400 | From | Steven Rostedt <> | Subject | [PATCH 3/9] ftrace: Optimize testing what context current is in |
| |
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
The preempt_count() is not a simple location in memory, it could be part of per_cpu code or more. Each access to preempt_count(), or one of its accessor functions (like in_interrupt()) takes several cycles. By reading preempt_count() once, and then doing tests to find the context against the value return is slightly faster than using in_nmi() and in_interrupt().
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> --- include/linux/trace_recursion.h | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/include/linux/trace_recursion.h b/include/linux/trace_recursion.h index da17a1144bf4..04d21e9ec48b 100644 --- a/include/linux/trace_recursion.h +++ b/include/linux/trace_recursion.h @@ -111,22 +111,29 @@ enum { #define TRACE_CONTEXT_MASK TRACE_LIST_MAX +/* + * Used for setting context + * NMI = 0 + * IRQ = 1 + * SOFTIRQ = 2 + * NORMAL = 3 + */ +enum { + TRACE_CTX_NMI, + TRACE_CTX_IRQ, + TRACE_CTX_SOFTIRQ, + TRACE_CTX_NORMAL, +}; + static __always_inline int trace_get_context_bit(void) { - int bit; - - if (in_interrupt()) { - if (in_nmi()) - bit = 0; + unsigned long pc = preempt_count(); - else if (in_irq()) - bit = 1; - else - bit = 2; - } else - bit = 3; - - return bit; + if (!(pc & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET))) + return TRACE_CTX_NORMAL; + else + return pc & NMI_MASK ? TRACE_CTX_NMI : + pc & HARDIRQ_MASK ? TRACE_CTX_IRQ : TRACE_CTX_SOFTIRQ; } static __always_inline int trace_test_and_set_recursion(int start, int max) -- 2.28.0
| |