4747#include <asm/mach/arch.h>
4848#include <asm/mpu.h>
4949
50+ #define CREATE_TRACE_POINTS
51+ #include <trace/events/ipi.h>
52+
5053/*
5154 * as from 2.5, kernels no longer have an init_tasks structure
5255 * so we need some other way of telling a new secondary core
@@ -430,38 +433,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
430433 }
431434}
432435
433- static void (* smp_cross_call )(const struct cpumask * , unsigned int );
436+ static void (* __smp_cross_call )(const struct cpumask * , unsigned int );
434437
435438void __init set_smp_cross_call (void (* fn )(const struct cpumask * , unsigned int ))
436439{
437- if (!smp_cross_call )
438- smp_cross_call = fn ;
439- }
440-
441- void arch_send_call_function_ipi_mask (const struct cpumask * mask )
442- {
443- smp_cross_call (mask , IPI_CALL_FUNC );
444- }
445-
446- void arch_send_wakeup_ipi_mask (const struct cpumask * mask )
447- {
448- smp_cross_call (mask , IPI_WAKEUP );
449- }
450-
451- void arch_send_call_function_single_ipi (int cpu )
452- {
453- smp_cross_call (cpumask_of (cpu ), IPI_CALL_FUNC_SINGLE );
440+ if (!__smp_cross_call )
441+ __smp_cross_call = fn ;
454442}
455443
456- #ifdef CONFIG_IRQ_WORK
457- void arch_irq_work_raise (void )
458- {
459- if (is_smp ())
460- smp_cross_call (cpumask_of (smp_processor_id ()), IPI_IRQ_WORK );
461- }
462- #endif
463-
464- static const char * ipi_types [NR_IPI ] = {
444+ static const char * ipi_types [NR_IPI ] __tracepoint_string = {
465445#define S (x ,s ) [x ] = s
466446 S (IPI_WAKEUP , "CPU wakeup interrupts" ),
467447 S (IPI_TIMER , "Timer broadcast interrupts" ),
@@ -473,6 +453,12 @@ static const char *ipi_types[NR_IPI] = {
473453 S (IPI_COMPLETION , "completion interrupts" ),
474454};
475455
456+ static void smp_cross_call (const struct cpumask * target , unsigned int ipinr )
457+ {
458+ trace_ipi_raise (target , ipi_types [ipinr ]);
459+ __smp_cross_call (target , ipinr );
460+ }
461+
476462void show_ipi_list (struct seq_file * p , int prec )
477463{
478464 unsigned int cpu , i ;
@@ -499,6 +485,29 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
499485 return sum ;
500486}
501487
488+ void arch_send_call_function_ipi_mask (const struct cpumask * mask )
489+ {
490+ smp_cross_call (mask , IPI_CALL_FUNC );
491+ }
492+
493+ void arch_send_wakeup_ipi_mask (const struct cpumask * mask )
494+ {
495+ smp_cross_call (mask , IPI_WAKEUP );
496+ }
497+
498+ void arch_send_call_function_single_ipi (int cpu )
499+ {
500+ smp_cross_call (cpumask_of (cpu ), IPI_CALL_FUNC_SINGLE );
501+ }
502+
503+ #ifdef CONFIG_IRQ_WORK
504+ void arch_irq_work_raise (void )
505+ {
506+ if (is_smp ())
507+ smp_cross_call (cpumask_of (smp_processor_id ()), IPI_IRQ_WORK );
508+ }
509+ #endif
510+
502511#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
503512void tick_broadcast (const struct cpumask * mask )
504513{
@@ -556,8 +565,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
556565 unsigned int cpu = smp_processor_id ();
557566 struct pt_regs * old_regs = set_irq_regs (regs );
558567
559- if (ipinr < NR_IPI )
568+ if ((unsigned )ipinr < NR_IPI ) {
569+ trace_ipi_entry (ipi_types [ipinr ]);
560570 __inc_irq_stat (cpu , ipi_irqs [ipinr ]);
571+ }
561572
562573 switch (ipinr ) {
563574 case IPI_WAKEUP :
@@ -612,6 +623,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
612623 cpu , ipinr );
613624 break ;
614625 }
626+
627+ if ((unsigned )ipinr < NR_IPI )
628+ trace_ipi_exit (ipi_types [ipinr ]);
615629 set_irq_regs (old_regs );
616630}
617631
0 commit comments