Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/tracing: Disentangle pagefault and resched IPI tracing key

The pagefault and the resched IPI handler are the only ones where it is
worth to optimize the code further in case tracepoints are disabled. But it
makes no sense to have a single static key for both.

Seperate the static keys so the facilities are handled seperately.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/20170828064957.536699116@linutronix.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Thomas Gleixner and committed by
Ingo Molnar
80954747 6f54f3ec

+59 -22
+8 -7
arch/x86/include/asm/trace/common.h
··· 1 1 #ifndef _ASM_TRACE_COMMON_H 2 2 #define _ASM_TRACE_COMMON_H 3 3 4 - extern int trace_irq_vector_regfunc(void); 5 - extern void trace_irq_vector_unregfunc(void); 6 - 7 4 #ifdef CONFIG_TRACING 8 - DECLARE_STATIC_KEY_FALSE(trace_irqvectors_key); 9 - #define trace_irqvectors_enabled() \ 10 - static_branch_unlikely(&trace_irqvectors_key) 5 + DECLARE_STATIC_KEY_FALSE(trace_pagefault_key); 6 + #define trace_pagefault_enabled() \ 7 + static_branch_unlikely(&trace_pagefault_key) 8 + DECLARE_STATIC_KEY_FALSE(trace_resched_ipi_key); 9 + #define trace_resched_ipi_enabled() \ 10 + static_branch_unlikely(&trace_resched_ipi_key) 11 11 #else 12 - static inline bool trace_irqvectors_enabled(void) { return false; } 12 + static inline bool trace_pagefault_enabled(void) { return false; } 13 + static inline bool trace_resched_ipi_enabled(void) { return false; } 13 14 #endif 14 15 15 16 #endif
+4 -2
arch/x86/include/asm/trace/exceptions.h
··· 7 7 #include <linux/tracepoint.h> 8 8 #include <asm/trace/common.h> 9 9 10 + extern int trace_pagefault_reg(void); 11 + extern void trace_pagefault_unreg(void); 12 + 10 13 DECLARE_EVENT_CLASS(x86_exceptions, 11 14 12 15 TP_PROTO(unsigned long address, struct pt_regs *regs, ··· 38 35 TP_PROTO(unsigned long address, struct pt_regs *regs, \ 39 36 unsigned long error_code), \ 40 37 TP_ARGS(address, regs, error_code), \ 41 - trace_irq_vector_regfunc, \ 42 - trace_irq_vector_unregfunc); 38 + trace_pagefault_reg, trace_pagefault_unreg); 43 39 44 40 DEFINE_PAGE_FAULT_EVENT(page_fault_user); 45 41 DEFINE_PAGE_FAULT_EVENT(page_fault_kernel);
+23 -6
arch/x86/include/asm/trace/irq_vectors.h
··· 7 7 #include <linux/tracepoint.h> 8 8 #include <asm/trace/common.h> 9 9 10 + extern int trace_resched_ipi_reg(void); 11 + extern void trace_resched_ipi_unreg(void); 12 + 10 13 DECLARE_EVENT_CLASS(x86_irq_vector, 11 14 12 15 TP_PROTO(int vector), ··· 29 26 #define DEFINE_IRQ_VECTOR_EVENT(name) \ 30 27 DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ 31 28 TP_PROTO(int vector), \ 29 + TP_ARGS(vector), NULL, NULL); \ 30 + DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ 31 + TP_PROTO(int vector), \ 32 + TP_ARGS(vector), NULL, NULL); 33 + 34 + #define DEFINE_RESCHED_IPI_EVENT(name) \ 35 + DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ 36 + TP_PROTO(int vector), \ 32 37 TP_ARGS(vector), \ 33 - trace_irq_vector_regfunc, \ 34 - trace_irq_vector_unregfunc); \ 38 + trace_resched_ipi_reg, \ 39 + trace_resched_ipi_unreg); \ 35 40 DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ 36 41 TP_PROTO(int vector), \ 37 42 TP_ARGS(vector), \ 38 - trace_irq_vector_regfunc, \ 39 - trace_irq_vector_unregfunc); 40 - 43 + trace_resched_ipi_reg, \ 44 + trace_resched_ipi_unreg); 41 45 42 46 /* 43 47 * local_timer - called when entering/exiting a local timer interrupt ··· 53 43 DEFINE_IRQ_VECTOR_EVENT(local_timer); 54 44 55 45 /* 46 + * The ifdef is required because that tracepoint macro hell emits tracepoint 47 + * code in files which include this header even if the tracepoint is not 48 + * enabled. Brilliant stuff that. 49 + */ 50 + #ifdef CONFIG_SMP 51 + /* 56 52 * reschedule - called when entering/exiting a reschedule vector handler 57 53 */ 58 - DEFINE_IRQ_VECTOR_EVENT(reschedule); 54 + DEFINE_RESCHED_IPI_EVENT(reschedule); 55 + #endif 59 56 60 57 /* 61 58 * spurious_apic - called when entering/exiting a spurious apic vector handler
+1 -1
arch/x86/kernel/smp.c
··· 262 262 ack_APIC_irq(); 263 263 inc_irq_stat(irq_resched_count); 264 264 265 - if (trace_irqvectors_enabled()) { 265 + if (trace_resched_ipi_enabled()) { 266 266 /* 267 267 * scheduler_ipi() might call irq_enter() as well, but 268 268 * nested calls are fine.
+22 -5
arch/x86/kernel/tracepoint.c
··· 10 10 #include <asm/hw_irq.h> 11 11 #include <asm/desc.h> 12 12 13 - DEFINE_STATIC_KEY_FALSE(trace_irqvectors_key); 13 + DEFINE_STATIC_KEY_FALSE(trace_pagefault_key); 14 14 15 - int trace_irq_vector_regfunc(void) 15 + int trace_pagefault_reg(void) 16 16 { 17 - static_branch_inc(&trace_irqvectors_key); 17 + static_branch_inc(&trace_pagefault_key); 18 18 return 0; 19 19 } 20 20 21 - void trace_irq_vector_unregfunc(void) 21 + void trace_pagefault_unreg(void) 22 22 { 23 - static_branch_dec(&trace_irqvectors_key); 23 + static_branch_dec(&trace_pagefault_key); 24 24 } 25 + 26 + #ifdef CONFIG_SMP 27 + 28 + DEFINE_STATIC_KEY_FALSE(trace_resched_ipi_key); 29 + 30 + int trace_resched_ipi_reg(void) 31 + { 32 + static_branch_inc(&trace_resched_ipi_key); 33 + return 0; 34 + } 35 + 36 + void trace_resched_ipi_unreg(void) 37 + { 38 + static_branch_dec(&trace_resched_ipi_key); 39 + } 40 + 41 + #endif
+1 -1
arch/x86/mm/fault.c
··· 1510 1510 enum ctx_state prev_state; 1511 1511 1512 1512 prev_state = exception_enter(); 1513 - if (trace_irqvectors_enabled()) 1513 + if (trace_pagefault_enabled()) 1514 1514 trace_page_fault_entries(address, regs, error_code); 1515 1515 1516 1516 __do_page_fault(regs, error_code, address);