diff options
author | Chris Redpath <chris.redpath@arm.com> | 2013-10-11 11:45:00 +0100 |
---|---|---|
committer | Jon Medhurst <tixy@linaro.org> | 2013-10-11 15:07:18 +0100 |
commit | 2353c1f8009c14e89b323b18ae246c485fc034e4 (patch) | |
tree | f6e207a94b4364410c55526c9445203dc3f46f69 | |
parent | 7b8e0b3f2af55b1ffb5c10be1daa59d8dc21d140 (diff) |
arm: ipi raise/start/end tracing
Add tracepoints for IPI raise events, and start and end of the
ipi handler.
Used to inspect the source of CPU wake-ups which are not already
traced - all other reasons for a CPU to wake-up are already
covered.
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>
-rw-r--r-- | arch/arm/kernel/smp.c | 5 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic.c | 5 | ||||
-rw-r--r-- | include/trace/events/arm-ipi.h | 100 |
3 files changed, 109 insertions, 1 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 5919eb451bb..80cd1ac1e0d 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -46,6 +46,9 @@ #include <asm/virt.h> #include <asm/mach/arch.h> +#define CREATE_TRACE_POINTS +#include <trace/events/arm-ipi.h> + /* * as from 2.5, kernels no longer have an init_tasks structure * so we need some other way of telling a new secondary core @@ -604,6 +607,7 @@ void handle_IPI(int ipinr, struct pt_regs *regs) if (ipinr < NR_IPI) __inc_irq_stat(cpu, ipi_irqs[ipinr]); + trace_arm_ipi_entry(ipinr); switch (ipinr) { case IPI_WAKEUP: break; @@ -643,6 +647,7 @@ void handle_IPI(int ipinr, struct pt_regs *regs) cpu, ipinr); break; } + trace_arm_ipi_exit(ipinr); set_irq_regs(old_regs); } diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 19ceaa60e0f..5dc511c5872 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -41,6 +41,7 @@ #include <linux/slab.h> #include <linux/irqchip/chained_irq.h> #include <linux/irqchip/arm-gic.h> +#include <trace/events/arm-ipi.h> #include <asm/irq.h> #include <asm/exception.h> @@ -649,8 +650,10 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) unsigned long map = 0; /* Convert our logical CPU mask into a physical one. */ - for_each_cpu(cpu, mask) + for_each_cpu(cpu, mask) { + trace_arm_ipi_send(irq, cpu); map |= gic_cpu_map[cpu]; + } /* * Ensure that stores to Normal memory are visible to the diff --git a/include/trace/events/arm-ipi.h b/include/trace/events/arm-ipi.h new file mode 100644 index 00000000000..5d3bd21827b --- /dev/null +++ b/include/trace/events/arm-ipi.h @@ -0,0 +1,100 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM arm-ipi + +#if !defined(_TRACE_ARM_IPI_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_ARM_IPI_H + +#include <linux/tracepoint.h> + +#define show_arm_ipi_name(val) \ + __print_symbolic(val, \ + { 0, "IPI_WAKEUP" }, \ + { 1, "IPI_TIMER" }, \ + { 2, "IPI_RESCHEDULE" }, \ + { 3, "IPI_CALL_FUNC" }, \ + { 4, "IPI_CALL_FUNC_SINGLE" }, \ + { 5, "IPI_CPU_STOP" }, \ + { 6, "IPI_COMPLETION" }, \ + { 7, "IPI_CPU_BACKTRACE" }) + +DECLARE_EVENT_CLASS(arm_ipi, + + TP_PROTO(unsigned int ipi_nr), + + TP_ARGS(ipi_nr), + + TP_STRUCT__entry( + __field( unsigned int, ipi ) + ), + + TP_fast_assign( + __entry->ipi = ipi_nr; + ), + + TP_printk("ipi=%u [action=%s]", __entry->ipi, + show_arm_ipi_name(__entry->ipi)) +); + +/** + * arm_ipi_entry - called in the arm-generic ipi handler immediately before + * entering ipi-type handler + * @ipi_nr: ipi number + * + * When used in combination with the arm_ipi_exit tracepoint + * we can determine the ipi handler runtine. + */ +DEFINE_EVENT(arm_ipi, arm_ipi_entry, + + TP_PROTO(unsigned int ipi_nr), + + TP_ARGS(ipi_nr) +); + +/** + * arm_ipi_exit - called in the arm-generic ipi handler immediately + * after the ipi-type handler returns + * @ipi_nr: ipi number + * + * When used in combination with the arm_ipi_entry tracepoint + * we can determine the ipi handler runtine. + */ +DEFINE_EVENT(arm_ipi, arm_ipi_exit, + + TP_PROTO(unsigned int ipi_nr), + + TP_ARGS(ipi_nr) +); + +/** + * arm_ipi_send - called as the ipi target mask is built, immediately + * before the register is written + * @ipi_nr: ipi number + * @dest: cpu to send to + * + * When used in combination with the arm_ipi_entry tracepoint + * we can determine the ipi raise to run latency. + */ +TRACE_EVENT(arm_ipi_send, + + TP_PROTO(unsigned int ipi_nr, int dest), + + TP_ARGS(ipi_nr, dest), + + TP_STRUCT__entry( + __field( unsigned int, ipi ) + __field( int , dest ) + ), + + TP_fast_assign( + __entry->ipi = ipi_nr; + __entry->dest = dest; + ), + + TP_printk("dest=%d ipi=%u [action=%s]", __entry->dest, + __entry->ipi, show_arm_ipi_name(__entry->ipi)) +); + +#endif /* _TRACE_ARM_IPI_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> |