aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/oprofile
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-09-30 06:16:26 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-30 06:16:26 -0400
commit59293c8ad54726150cf6178164311b004d615ce4 (patch)
tree6fcf8e59a2c9ac08a4ff092544c34d2254ac0d74 /arch/x86/oprofile
parent45f197ade73ba95681b9803680c75352fc0a1c0a (diff)
parent94aca1dac6f6d21f4b07e4864baf7768cabcc6e7 (diff)
Merge commit 'v2.6.27-rc8' into oprofile
Conflicts: arch/x86/oprofile/nmi_int.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/oprofile')
-rw-r--r--arch/x86/oprofile/nmi_int.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 4108d02c5292..114df508b407 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -16,6 +16,7 @@
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/moduleparam.h> 17#include <linux/moduleparam.h>
18#include <linux/kdebug.h> 18#include <linux/kdebug.h>
19#include <linux/cpu.h>
19#include <asm/nmi.h> 20#include <asm/nmi.h>
20#include <asm/msr.h> 21#include <asm/msr.h>
21#include <asm/apic.h> 22#include <asm/apic.h>
@@ -31,27 +32,50 @@ static DEFINE_PER_CPU(unsigned long, saved_lvtpc);
31 32
32static int nmi_start(void); 33static int nmi_start(void);
33static void nmi_stop(void); 34static void nmi_stop(void);
35static void nmi_cpu_start(void *dummy);
36static void nmi_cpu_stop(void *dummy);
34static void nmi_cpu_save_mpx_registers(struct op_msrs *msrs); 37static void nmi_cpu_save_mpx_registers(struct op_msrs *msrs);
35static void nmi_cpu_restore_mpx_registers(struct op_msrs *msrs); 38static void nmi_cpu_restore_mpx_registers(struct op_msrs *msrs);
36static void nmi_cpu_stop(void *dummy);
37static void nmi_cpu_start(void *dummy);
38 39
39/* 0 == registered but off, 1 == registered and on */ 40/* 0 == registered but off, 1 == registered and on */
40static int nmi_enabled = 0; 41static int nmi_enabled = 0;
41 42
43#ifdef CONFIG_SMP
44static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
45 void *data)
46{
47 int cpu = (unsigned long)data;
48 switch (action) {
49 case CPU_DOWN_FAILED:
50 case CPU_ONLINE:
51 smp_call_function_single(cpu, nmi_cpu_start, NULL, 0);
52 break;
53 case CPU_DOWN_PREPARE:
54 smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1);
55 break;
56 }
57 return NOTIFY_DONE;
58}
59
60static struct notifier_block oprofile_cpu_nb = {
61 .notifier_call = oprofile_cpu_notifier
62};
63#endif
64
42#ifdef CONFIG_PM 65#ifdef CONFIG_PM
43 66
44static int nmi_suspend(struct sys_device *dev, pm_message_t state) 67static int nmi_suspend(struct sys_device *dev, pm_message_t state)
45{ 68{
69 /* Only one CPU left, just stop that one */
46 if (nmi_enabled == 1) 70 if (nmi_enabled == 1)
47 nmi_stop(); 71 nmi_cpu_stop(NULL);
48 return 0; 72 return 0;
49} 73}
50 74
51static int nmi_resume(struct sys_device *dev) 75static int nmi_resume(struct sys_device *dev)
52{ 76{
53 if (nmi_enabled == 1) 77 if (nmi_enabled == 1)
54 nmi_start(); 78 nmi_cpu_start(NULL);
55 return 0; 79 return 0;
56} 80}
57 81
@@ -351,10 +375,12 @@ static void nmi_cpu_shutdown(void *dummy)
351 375
352static void nmi_shutdown(void) 376static void nmi_shutdown(void)
353{ 377{
354 struct op_msrs *msrs = &get_cpu_var(cpu_msrs); 378 struct op_msrs *msrs;
379
355 nmi_enabled = 0; 380 nmi_enabled = 0;
356 on_each_cpu(nmi_cpu_shutdown, NULL, 1); 381 on_each_cpu(nmi_cpu_shutdown, NULL, 1);
357 unregister_die_notifier(&profile_exceptions_nb); 382 unregister_die_notifier(&profile_exceptions_nb);
383 msrs = &get_cpu_var(cpu_msrs);
358 model->shutdown(msrs); 384 model->shutdown(msrs);
359 free_msrs(); 385 free_msrs();
360 put_cpu_var(cpu_msrs); 386 put_cpu_var(cpu_msrs);
@@ -550,6 +576,9 @@ int __init op_nmi_init(struct oprofile_operations *ops)
550 return -ENODEV; 576 return -ENODEV;
551 } 577 }
552 578
579#ifdef CONFIG_SMP
580 register_cpu_notifier(&oprofile_cpu_nb);
581#endif
553 /* default values, can be overwritten by model */ 582 /* default values, can be overwritten by model */
554 __raw_get_cpu_var(switch_index) = 0; 583 __raw_get_cpu_var(switch_index) = 0;
555 ops->create_files = nmi_create_files; 584 ops->create_files = nmi_create_files;
@@ -573,8 +602,12 @@ int __init op_nmi_init(struct oprofile_operations *ops)
573 602
574void op_nmi_exit(void) 603void op_nmi_exit(void)
575{ 604{
576 if (using_nmi) 605 if (using_nmi) {
577 exit_sysfs(); 606 exit_sysfs();
607#ifdef CONFIG_SMP
608 unregister_cpu_notifier(&oprofile_cpu_nb);
609#endif
578 if (model->exit) 610 if (model->exit)
579 model->exit(); 611 model->exit();
612 }
580} 613}