Commit 80954747 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Ingo Molnar

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: default avatarThomas 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.deSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 6f54f3ec
#ifndef _ASM_TRACE_COMMON_H #ifndef _ASM_TRACE_COMMON_H
#define _ASM_TRACE_COMMON_H #define _ASM_TRACE_COMMON_H
extern int trace_irq_vector_regfunc(void);
extern void trace_irq_vector_unregfunc(void);
#ifdef CONFIG_TRACING #ifdef CONFIG_TRACING
DECLARE_STATIC_KEY_FALSE(trace_irqvectors_key); DECLARE_STATIC_KEY_FALSE(trace_pagefault_key);
#define trace_irqvectors_enabled() \ #define trace_pagefault_enabled() \
static_branch_unlikely(&trace_irqvectors_key) static_branch_unlikely(&trace_pagefault_key)
DECLARE_STATIC_KEY_FALSE(trace_resched_ipi_key);
#define trace_resched_ipi_enabled() \
static_branch_unlikely(&trace_resched_ipi_key)
#else #else
static inline bool trace_irqvectors_enabled(void) { return false; } static inline bool trace_pagefault_enabled(void) { return false; }
static inline bool trace_resched_ipi_enabled(void) { return false; }
#endif #endif
#endif #endif
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
#include <linux/tracepoint.h> #include <linux/tracepoint.h>
#include <asm/trace/common.h> #include <asm/trace/common.h>
extern int trace_pagefault_reg(void);
extern void trace_pagefault_unreg(void);
DECLARE_EVENT_CLASS(x86_exceptions, DECLARE_EVENT_CLASS(x86_exceptions,
TP_PROTO(unsigned long address, struct pt_regs *regs, TP_PROTO(unsigned long address, struct pt_regs *regs,
...@@ -35,8 +38,7 @@ DEFINE_EVENT_FN(x86_exceptions, name, \ ...@@ -35,8 +38,7 @@ DEFINE_EVENT_FN(x86_exceptions, name, \
TP_PROTO(unsigned long address, struct pt_regs *regs, \ TP_PROTO(unsigned long address, struct pt_regs *regs, \
unsigned long error_code), \ unsigned long error_code), \
TP_ARGS(address, regs, error_code), \ TP_ARGS(address, regs, error_code), \
trace_irq_vector_regfunc, \ trace_pagefault_reg, trace_pagefault_unreg);
trace_irq_vector_unregfunc);
DEFINE_PAGE_FAULT_EVENT(page_fault_user); DEFINE_PAGE_FAULT_EVENT(page_fault_user);
DEFINE_PAGE_FAULT_EVENT(page_fault_kernel); DEFINE_PAGE_FAULT_EVENT(page_fault_kernel);
......
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
#include <linux/tracepoint.h> #include <linux/tracepoint.h>
#include <asm/trace/common.h> #include <asm/trace/common.h>
extern int trace_resched_ipi_reg(void);
extern void trace_resched_ipi_unreg(void);
DECLARE_EVENT_CLASS(x86_irq_vector, DECLARE_EVENT_CLASS(x86_irq_vector,
TP_PROTO(int vector), TP_PROTO(int vector),
...@@ -24,17 +27,24 @@ DECLARE_EVENT_CLASS(x86_irq_vector, ...@@ -24,17 +27,24 @@ DECLARE_EVENT_CLASS(x86_irq_vector,
TP_printk("vector=%d", __entry->vector) ); TP_printk("vector=%d", __entry->vector) );
#define DEFINE_IRQ_VECTOR_EVENT(name) \ #define DEFINE_IRQ_VECTOR_EVENT(name) \
DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \
TP_PROTO(int vector), \
TP_ARGS(vector), NULL, NULL); \
DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \
TP_PROTO(int vector), \
TP_ARGS(vector), NULL, NULL);
#define DEFINE_RESCHED_IPI_EVENT(name) \
DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \
TP_PROTO(int vector), \ TP_PROTO(int vector), \
TP_ARGS(vector), \ TP_ARGS(vector), \
trace_irq_vector_regfunc, \ trace_resched_ipi_reg, \
trace_irq_vector_unregfunc); \ trace_resched_ipi_unreg); \
DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \
TP_PROTO(int vector), \ TP_PROTO(int vector), \
TP_ARGS(vector), \ TP_ARGS(vector), \
trace_irq_vector_regfunc, \ trace_resched_ipi_reg, \
trace_irq_vector_unregfunc); trace_resched_ipi_unreg);
/* /*
* local_timer - called when entering/exiting a local timer interrupt * local_timer - called when entering/exiting a local timer interrupt
...@@ -42,10 +52,17 @@ DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ ...@@ -42,10 +52,17 @@ DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \
*/ */
DEFINE_IRQ_VECTOR_EVENT(local_timer); DEFINE_IRQ_VECTOR_EVENT(local_timer);
/*
* The ifdef is required because that tracepoint macro hell emits tracepoint
* code in files which include this header even if the tracepoint is not
* enabled. Brilliant stuff that.
*/
#ifdef CONFIG_SMP
/* /*
* reschedule - called when entering/exiting a reschedule vector handler * reschedule - called when entering/exiting a reschedule vector handler
*/ */
DEFINE_IRQ_VECTOR_EVENT(reschedule); DEFINE_RESCHED_IPI_EVENT(reschedule);
#endif
/* /*
* spurious_apic - called when entering/exiting a spurious apic vector handler * spurious_apic - called when entering/exiting a spurious apic vector handler
......
...@@ -262,7 +262,7 @@ __visible void __irq_entry smp_reschedule_interrupt(struct pt_regs *regs) ...@@ -262,7 +262,7 @@ __visible void __irq_entry smp_reschedule_interrupt(struct pt_regs *regs)
ack_APIC_irq(); ack_APIC_irq();
inc_irq_stat(irq_resched_count); inc_irq_stat(irq_resched_count);
if (trace_irqvectors_enabled()) { if (trace_resched_ipi_enabled()) {
/* /*
* scheduler_ipi() might call irq_enter() as well, but * scheduler_ipi() might call irq_enter() as well, but
* nested calls are fine. * nested calls are fine.
......
...@@ -10,15 +10,32 @@ ...@@ -10,15 +10,32 @@
#include <asm/hw_irq.h> #include <asm/hw_irq.h>
#include <asm/desc.h> #include <asm/desc.h>
DEFINE_STATIC_KEY_FALSE(trace_irqvectors_key); DEFINE_STATIC_KEY_FALSE(trace_pagefault_key);
int trace_irq_vector_regfunc(void) int trace_pagefault_reg(void)
{ {
static_branch_inc(&trace_irqvectors_key); static_branch_inc(&trace_pagefault_key);
return 0; return 0;
} }
void trace_irq_vector_unregfunc(void) void trace_pagefault_unreg(void)
{ {
static_branch_dec(&trace_irqvectors_key); static_branch_dec(&trace_pagefault_key);
} }
#ifdef CONFIG_SMP
DEFINE_STATIC_KEY_FALSE(trace_resched_ipi_key);
int trace_resched_ipi_reg(void)
{
static_branch_inc(&trace_resched_ipi_key);
return 0;
}
void trace_resched_ipi_unreg(void)
{
static_branch_dec(&trace_resched_ipi_key);
}
#endif
...@@ -1510,7 +1510,7 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -1510,7 +1510,7 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
enum ctx_state prev_state; enum ctx_state prev_state;
prev_state = exception_enter(); prev_state = exception_enter();
if (trace_irqvectors_enabled()) if (trace_pagefault_enabled())
trace_page_fault_entries(address, regs, error_code); trace_page_fault_entries(address, regs, error_code);
__do_page_fault(regs, error_code, address); __do_page_fault(regs, error_code, address);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment