mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 14:42:37 +02:00
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:
parent
2353c1f800
commit
5ecaba3d9f
91
include/trace/events/smp.h
Normal file
91
include/trace/events/smp.h
Normal 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>
|
||||
12
kernel/smp.c
12
kernel/smp.c
|
|
@ -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)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user