smp: smp_cross_call function pointer tracing

generic tracing for smp_cross_call function calls

Signed-off-by: Chris Redpath <chris.redpath@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Jon Medhurst <tixy@linaro.org>
This commit is contained in:
Chris Redpath 2013-10-11 11:45:01 +01:00 committed by Jon Medhurst
parent 2353c1f800
commit 5ecaba3d9f
2 changed files with 101 additions and 2 deletions

View File

@ -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 <linux/tracepoint.h>
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 <trace/define_trace.h>

View File

@ -12,6 +12,8 @@
#include <linux/gfp.h>
#include <linux/smp.h>
#include <linux/cpu.h>
#define CREATE_TRACE_POINTS
#include <trace/events/smp.h>
#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)) {