From 5ecaba3d9f4ab514fe8d383534e24b306f116896 Mon Sep 17 00:00:00 2001 From: Chris Redpath Date: Fri, 11 Oct 2013 11:45:01 +0100 Subject: [PATCH] smp: smp_cross_call function pointer tracing generic tracing for smp_cross_call function calls Signed-off-by: Chris Redpath Signed-off-by: Liviu Dudau Signed-off-by: Jon Medhurst --- include/trace/events/smp.h | 91 ++++++++++++++++++++++++++++++++++++++ kernel/smp.c | 12 ++++- 2 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 include/trace/events/smp.h diff --git a/include/trace/events/smp.h b/include/trace/events/smp.h new file mode 100644 index 000000000000..c8abfd744723 --- /dev/null +++ b/include/trace/events/smp.h @@ -0,0 +1,91 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM smp + +#if !defined(_TRACE_SMP_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SMP_H + +#include +typedef void (*__smp_call_func_t)(void *info); + +DECLARE_EVENT_CLASS(smp_call_class, + + TP_PROTO(__smp_call_func_t fnc), + + TP_ARGS(fnc), + + TP_STRUCT__entry( + __field( void *, func ) + ), + + TP_fast_assign( + __entry->func = fnc; + ), + + TP_printk("func=%pf", __entry->func) +); + +/** + * smp_call_func_entry - called in the generic smp-cross-call-handler + * immediately before calling the destination + * function + * @func: function pointer + * + * When used in combination with the smp_call_func_exit tracepoint + * we can determine the cross-call runtime. + */ +DEFINE_EVENT(smp_call_class, smp_call_func_entry, + + TP_PROTO(__smp_call_func_t fnc), + + TP_ARGS(fnc) +); + +/** + * smp_call_func_exit - called in the generic smp-cross-call-handler + * immediately after the destination function + * returns + * @func: function pointer + * + * When used in combination with the smp_call_entry tracepoint + * we can determine the cross-call runtime. + */ +DEFINE_EVENT(smp_call_class, smp_call_func_exit, + + TP_PROTO(__smp_call_func_t fnc), + + TP_ARGS(fnc) +); + +/** + * smp_call_func_send - called as destination function is set + * in the per-cpu storage + * @func: function pointer + * @dest: cpu to send to + * + * When used in combination with the smp_cross_call_entry tracepoint + * we can determine the call-to-run latency. + */ +TRACE_EVENT(smp_call_func_send, + + TP_PROTO(__smp_call_func_t func, int dest), + + TP_ARGS(func, dest), + + TP_STRUCT__entry( + __field( void * , func ) + __field( int , dest ) + ), + + TP_fast_assign( + __entry->func = func; + __entry->dest = dest; + ), + + TP_printk("dest=%d func=%pf", __entry->dest, + __entry->func) +); + +#endif /* _TRACE_SMP_H */ + +/* This part must be outside protection */ +#include diff --git a/kernel/smp.c b/kernel/smp.c index 4dba0f7b72ad..23ccc67dcbb2 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -12,6 +12,8 @@ #include #include #include +#define CREATE_TRACE_POINTS +#include #include "smpboot.h" @@ -159,8 +161,10 @@ void generic_exec_single(int cpu, struct call_single_data *csd, int wait) * locking and barrier primitives. Generic code isn't really * equipped to do the right thing... */ - if (ipi) + if (ipi) { + trace_smp_call_func_send(csd->func, cpu); arch_send_call_function_single_ipi(cpu); + } if (wait) csd_lock_wait(csd); @@ -197,8 +201,9 @@ void generic_smp_call_function_single_interrupt(void) * so save them away before making the call: */ csd_flags = csd->flags; - + trace_smp_call_func_entry(csd->func); csd->func(csd->info); + trace_smp_call_func_exit(csd->func); /* * Unlocked CSDs are valid through generic_exec_single(): @@ -228,6 +233,7 @@ int smp_call_function_single(int cpu, smp_call_func_t func, void *info, int this_cpu; int err = 0; + trace_smp_call_func_send(func, cpu); /* * prevent preemption and reschedule on another processor, * as well as CPU removal @@ -245,7 +251,9 @@ int smp_call_function_single(int cpu, smp_call_func_t func, void *info, if (cpu == this_cpu) { local_irq_save(flags); + trace_smp_call_func_entry(func); func(info); + trace_smp_call_func_exit(func); local_irq_restore(flags); } else { if ((unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) { -- 2.34.1