forked from Minki/linux
c49f63530b
Knowing how long we spend in firmware calls is an important part of minimising OS jitter. This patch adds tracepoints to each OPAL call. If tracepoints are enabled we branch out to a common routine that calls an entry and exit tracepoint. This allows us to write tools that monitor the frequency and duration of OPAL calls, eg: name count total(ms) min(ms) max(ms) avg(ms) period(ms) OPAL_HANDLE_INTERRUPT 5 0.199 0.037 0.042 0.040 12547.545 OPAL_POLL_EVENTS 204 2.590 0.012 0.036 0.013 2264.899 OPAL_PCI_MSI_EOI 2830 3.066 0.001 0.005 0.001 81.166 We use jump labels if configured, which means we only add a single nop instruction to every OPAL call when the tracepoints are disabled. Signed-off-by: Anton Blanchard <anton@samba.org> Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
156 lines
2.7 KiB
C
156 lines
2.7 KiB
C
#undef TRACE_SYSTEM
|
|
#define TRACE_SYSTEM powerpc
|
|
|
|
#if !defined(_TRACE_POWERPC_H) || defined(TRACE_HEADER_MULTI_READ)
|
|
#define _TRACE_POWERPC_H
|
|
|
|
#include <linux/tracepoint.h>
|
|
|
|
struct pt_regs;
|
|
|
|
DECLARE_EVENT_CLASS(ppc64_interrupt_class,
|
|
|
|
TP_PROTO(struct pt_regs *regs),
|
|
|
|
TP_ARGS(regs),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(struct pt_regs *, regs)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->regs = regs;
|
|
),
|
|
|
|
TP_printk("pt_regs=%p", __entry->regs)
|
|
);
|
|
|
|
DEFINE_EVENT(ppc64_interrupt_class, irq_entry,
|
|
|
|
TP_PROTO(struct pt_regs *regs),
|
|
|
|
TP_ARGS(regs)
|
|
);
|
|
|
|
DEFINE_EVENT(ppc64_interrupt_class, irq_exit,
|
|
|
|
TP_PROTO(struct pt_regs *regs),
|
|
|
|
TP_ARGS(regs)
|
|
);
|
|
|
|
DEFINE_EVENT(ppc64_interrupt_class, timer_interrupt_entry,
|
|
|
|
TP_PROTO(struct pt_regs *regs),
|
|
|
|
TP_ARGS(regs)
|
|
);
|
|
|
|
DEFINE_EVENT(ppc64_interrupt_class, timer_interrupt_exit,
|
|
|
|
TP_PROTO(struct pt_regs *regs),
|
|
|
|
TP_ARGS(regs)
|
|
);
|
|
|
|
#ifdef CONFIG_PPC_PSERIES
|
|
extern void hcall_tracepoint_regfunc(void);
|
|
extern void hcall_tracepoint_unregfunc(void);
|
|
|
|
TRACE_EVENT_FN(hcall_entry,
|
|
|
|
TP_PROTO(unsigned long opcode, unsigned long *args),
|
|
|
|
TP_ARGS(opcode, args),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned long, opcode)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->opcode = opcode;
|
|
),
|
|
|
|
TP_printk("opcode=%lu", __entry->opcode),
|
|
|
|
hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc
|
|
);
|
|
|
|
TRACE_EVENT_FN(hcall_exit,
|
|
|
|
TP_PROTO(unsigned long opcode, unsigned long retval,
|
|
unsigned long *retbuf),
|
|
|
|
TP_ARGS(opcode, retval, retbuf),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned long, opcode)
|
|
__field(unsigned long, retval)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->opcode = opcode;
|
|
__entry->retval = retval;
|
|
),
|
|
|
|
TP_printk("opcode=%lu retval=%lu", __entry->opcode, __entry->retval),
|
|
|
|
hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc
|
|
);
|
|
#endif
|
|
|
|
#ifdef CONFIG_PPC_POWERNV
|
|
extern void opal_tracepoint_regfunc(void);
|
|
extern void opal_tracepoint_unregfunc(void);
|
|
|
|
TRACE_EVENT_FN(opal_entry,
|
|
|
|
TP_PROTO(unsigned long opcode, unsigned long *args),
|
|
|
|
TP_ARGS(opcode, args),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned long, opcode)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->opcode = opcode;
|
|
),
|
|
|
|
TP_printk("opcode=%lu", __entry->opcode),
|
|
|
|
opal_tracepoint_regfunc, opal_tracepoint_unregfunc
|
|
);
|
|
|
|
TRACE_EVENT_FN(opal_exit,
|
|
|
|
TP_PROTO(unsigned long opcode, unsigned long retval),
|
|
|
|
TP_ARGS(opcode, retval),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(unsigned long, opcode)
|
|
__field(unsigned long, retval)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->opcode = opcode;
|
|
__entry->retval = retval;
|
|
),
|
|
|
|
TP_printk("opcode=%lu retval=%lu", __entry->opcode, __entry->retval),
|
|
|
|
opal_tracepoint_regfunc, opal_tracepoint_unregfunc
|
|
);
|
|
#endif
|
|
|
|
#endif /* _TRACE_POWERPC_H */
|
|
|
|
#undef TRACE_INCLUDE_PATH
|
|
#undef TRACE_INCLUDE_FILE
|
|
|
|
#define TRACE_INCLUDE_PATH asm
|
|
#define TRACE_INCLUDE_FILE trace
|
|
|
|
#include <trace/define_trace.h>
|