aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-09 20:33:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-09 20:33:44 -0400
commitc23190c0bf1236e1eb5521a8b10d0102fbc1338c (patch)
treeeb23225a121fb56a58d69d34e7338bfe81ede644 /arch
parentfc335c1b68c68f626f07f1819e57d112d666bbba (diff)
parent45ed695ac10a23cb4e60a3e0b68b3f21a8670670 (diff)
Merge tag 'trace-ipi-tracepoints' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull IPI tracepoints for ARM from Steven Rostedt: "Nicolas Pitre added generic tracepoints for tracing IPIs and updated the arm and arm64 architectures. It required some minor updates to the generic tracepoint system, so it had to wait for me to implement them" * tag 'trace-ipi-tracepoints' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: ARM64: add IPI tracepoints ARM: add IPI tracepoints tracepoint: add generic tracepoint definitions for IPI tracing tracing: Do not do anything special with tracepoint_string when tracing is disabled
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/smp.c70
-rw-r--r--arch/arm64/kernel/smp.c65
2 files changed, 81 insertions, 54 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 7c4fada440f0..9388a3d479e1 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -47,6 +47,9 @@
47#include <asm/mach/arch.h> 47#include <asm/mach/arch.h>
48#include <asm/mpu.h> 48#include <asm/mpu.h>
49 49
50#define CREATE_TRACE_POINTS
51#include <trace/events/ipi.h>
52
50/* 53/*
51 * as from 2.5, kernels no longer have an init_tasks structure 54 * as from 2.5, kernels no longer have an init_tasks structure
52 * so we need some other way of telling a new secondary core 55 * 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)
430 } 433 }
431} 434}
432 435
433static void (*smp_cross_call)(const struct cpumask *, unsigned int); 436static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
434 437
435void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) 438void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
436{ 439{
437 if (!smp_cross_call) 440 if (!__smp_cross_call)
438 smp_cross_call = fn; 441 __smp_cross_call = fn;
439}
440
441void arch_send_call_function_ipi_mask(const struct cpumask *mask)
442{
443 smp_cross_call(mask, IPI_CALL_FUNC);
444}
445
446void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
447{
448 smp_cross_call(mask, IPI_WAKEUP);
449}
450
451void arch_send_call_function_single_ipi(int cpu)
452{
453 smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
454} 442}
455 443
456#ifdef CONFIG_IRQ_WORK 444static const char *ipi_types[NR_IPI] __tracepoint_string = {
457void 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
464static const char *ipi_types[NR_IPI] = {
465#define S(x,s) [x] = s 445#define S(x,s) [x] = s
466 S(IPI_WAKEUP, "CPU wakeup interrupts"), 446 S(IPI_WAKEUP, "CPU wakeup interrupts"),
467 S(IPI_TIMER, "Timer broadcast interrupts"), 447 S(IPI_TIMER, "Timer broadcast interrupts"),
@@ -473,6 +453,12 @@ static const char *ipi_types[NR_IPI] = {
473 S(IPI_COMPLETION, "completion interrupts"), 453 S(IPI_COMPLETION, "completion interrupts"),
474}; 454};
475 455
456static 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
476void show_ipi_list(struct seq_file *p, int prec) 462void show_ipi_list(struct seq_file *p, int prec)
477{ 463{
478 unsigned int cpu, i; 464 unsigned int cpu, i;
@@ -499,6 +485,29 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
499 return sum; 485 return sum;
500} 486}
501 487
488void arch_send_call_function_ipi_mask(const struct cpumask *mask)
489{
490 smp_cross_call(mask, IPI_CALL_FUNC);
491}
492
493void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
494{
495 smp_cross_call(mask, IPI_WAKEUP);
496}
497
498void 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
504void 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
502#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 511#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
503void tick_broadcast(const struct cpumask *mask) 512void tick_broadcast(const struct cpumask *mask)
504{ 513{
@@ -556,8 +565,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
556 unsigned int cpu = smp_processor_id(); 565 unsigned int cpu = smp_processor_id();
557 struct pt_regs *old_regs = set_irq_regs(regs); 566 struct pt_regs *old_regs = set_irq_regs(regs);
558 567
559 if (ipinr < NR_IPI) 568 if ((unsigned)ipinr < NR_IPI) {
569 trace_ipi_entry(ipi_types[ipinr]);
560 __inc_irq_stat(cpu, ipi_irqs[ipinr]); 570 __inc_irq_stat(cpu, ipi_irqs[ipinr]);
571 }
561 572
562 switch (ipinr) { 573 switch (ipinr) {
563 case IPI_WAKEUP: 574 case IPI_WAKEUP:
@@ -612,6 +623,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
612 cpu, ipinr); 623 cpu, ipinr);
613 break; 624 break;
614 } 625 }
626
627 if ((unsigned)ipinr < NR_IPI)
628 trace_ipi_exit(ipi_types[ipinr]);
615 set_irq_regs(old_regs); 629 set_irq_regs(old_regs);
616} 630}
617 631
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 3e2f5ebbf63e..474339718105 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -51,6 +51,9 @@
51#include <asm/tlbflush.h> 51#include <asm/tlbflush.h>
52#include <asm/ptrace.h> 52#include <asm/ptrace.h>
53 53
54#define CREATE_TRACE_POINTS
55#include <trace/events/ipi.h>
56
54/* 57/*
55 * as from 2.5, kernels no longer have an init_tasks structure 58 * as from 2.5, kernels no longer have an init_tasks structure
56 * so we need some other way of telling a new secondary core 59 * so we need some other way of telling a new secondary core
@@ -313,8 +316,6 @@ void __init smp_prepare_boot_cpu(void)
313 set_my_cpu_offset(per_cpu_offset(smp_processor_id())); 316 set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
314} 317}
315 318
316static void (*smp_cross_call)(const struct cpumask *, unsigned int);
317
318/* 319/*
319 * Enumerate the possible CPU set from the device tree and build the 320 * Enumerate the possible CPU set from the device tree and build the
320 * cpu logical map array containing MPIDR values related to logical 321 * cpu logical map array containing MPIDR values related to logical
@@ -469,32 +470,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
469 } 470 }
470} 471}
471 472
473static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
472 474
473void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) 475void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
474{ 476{
475 smp_cross_call = fn; 477 __smp_cross_call = fn;
476} 478}
477 479
478void arch_send_call_function_ipi_mask(const struct cpumask *mask) 480static const char *ipi_types[NR_IPI] __tracepoint_string = {
479{ 481#define S(x,s) [x] = s
480 smp_cross_call(mask, IPI_CALL_FUNC);
481}
482
483void arch_send_call_function_single_ipi(int cpu)
484{
485 smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
486}
487
488#ifdef CONFIG_IRQ_WORK
489void arch_irq_work_raise(void)
490{
491 if (smp_cross_call)
492 smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
493}
494#endif
495
496static const char *ipi_types[NR_IPI] = {
497#define S(x,s) [x - IPI_RESCHEDULE] = s
498 S(IPI_RESCHEDULE, "Rescheduling interrupts"), 482 S(IPI_RESCHEDULE, "Rescheduling interrupts"),
499 S(IPI_CALL_FUNC, "Function call interrupts"), 483 S(IPI_CALL_FUNC, "Function call interrupts"),
500 S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"), 484 S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
@@ -503,12 +487,18 @@ static const char *ipi_types[NR_IPI] = {
503 S(IPI_IRQ_WORK, "IRQ work interrupts"), 487 S(IPI_IRQ_WORK, "IRQ work interrupts"),
504}; 488};
505 489
490static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
491{
492 trace_ipi_raise(target, ipi_types[ipinr]);
493 __smp_cross_call(target, ipinr);
494}
495
506void show_ipi_list(struct seq_file *p, int prec) 496void show_ipi_list(struct seq_file *p, int prec)
507{ 497{
508 unsigned int cpu, i; 498 unsigned int cpu, i;
509 499
510 for (i = 0; i < NR_IPI; i++) { 500 for (i = 0; i < NR_IPI; i++) {
511 seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i + IPI_RESCHEDULE, 501 seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
512 prec >= 4 ? " " : ""); 502 prec >= 4 ? " " : "");
513 for_each_online_cpu(cpu) 503 for_each_online_cpu(cpu)
514 seq_printf(p, "%10u ", 504 seq_printf(p, "%10u ",
@@ -528,6 +518,24 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
528 return sum; 518 return sum;
529} 519}
530 520
521void arch_send_call_function_ipi_mask(const struct cpumask *mask)
522{
523 smp_cross_call(mask, IPI_CALL_FUNC);
524}
525
526void arch_send_call_function_single_ipi(int cpu)
527{
528 smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
529}
530
531#ifdef CONFIG_IRQ_WORK
532void arch_irq_work_raise(void)
533{
534 if (__smp_cross_call)
535 smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
536}
537#endif
538
531static DEFINE_RAW_SPINLOCK(stop_lock); 539static DEFINE_RAW_SPINLOCK(stop_lock);
532 540
533/* 541/*
@@ -559,8 +567,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
559 unsigned int cpu = smp_processor_id(); 567 unsigned int cpu = smp_processor_id();
560 struct pt_regs *old_regs = set_irq_regs(regs); 568 struct pt_regs *old_regs = set_irq_regs(regs);
561 569
562 if (ipinr >= IPI_RESCHEDULE && ipinr < IPI_RESCHEDULE + NR_IPI) 570 if ((unsigned)ipinr < NR_IPI) {
563 __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_RESCHEDULE]); 571 trace_ipi_entry(ipi_types[ipinr]);
572 __inc_irq_stat(cpu, ipi_irqs[ipinr]);
573 }
564 574
565 switch (ipinr) { 575 switch (ipinr) {
566 case IPI_RESCHEDULE: 576 case IPI_RESCHEDULE:
@@ -605,6 +615,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
605 pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); 615 pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
606 break; 616 break;
607 } 617 }
618
619 if ((unsigned)ipinr < NR_IPI)
620 trace_ipi_exit(ipi_types[ipinr]);
608 set_irq_regs(old_regs); 621 set_irq_regs(old_regs);
609} 622}
610 623