aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/oprofile/nmi_int.c
diff options
context:
space:
mode:
authorRobert Richter <robert.richter@amd.com>2008-09-24 05:25:31 -0400
committerRobert Richter <robert.richter@amd.com>2008-09-24 05:25:31 -0400
commitf78e80209cf143be49f268c340431ae9fa3abb74 (patch)
tree820fa64b688099dfdd93d27ba03252738ca5c7e2 /arch/x86/oprofile/nmi_int.c
parent4c168eaf7ea39f25a45a3d8c7eebc3fedb633a1d (diff)
parent24342c34a022ee90839873d91396045e12ef1090 (diff)
Merge commit 'v2.6.27-rc5' into tip/oprofile
Conflicts: arch/x86/oprofile/nmi_int.c
Diffstat (limited to 'arch/x86/oprofile/nmi_int.c')
-rw-r--r--arch/x86/oprofile/nmi_int.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 287513a09819..d98857410746 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>
@@ -29,23 +30,48 @@ static DEFINE_PER_CPU(unsigned long, saved_lvtpc);
29 30
30static int nmi_start(void); 31static int nmi_start(void);
31static void nmi_stop(void); 32static void nmi_stop(void);
33static void nmi_cpu_start(void *dummy);
34static void nmi_cpu_stop(void *dummy);
32 35
33/* 0 == registered but off, 1 == registered and on */ 36/* 0 == registered but off, 1 == registered and on */
34static int nmi_enabled = 0; 37static int nmi_enabled = 0;
35 38
39#ifdef CONFIG_SMP
40static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
41 void *data)
42{
43 int cpu = (unsigned long)data;
44 switch (action) {
45 case CPU_DOWN_FAILED:
46 case CPU_ONLINE:
47 smp_call_function_single(cpu, nmi_cpu_start, NULL, 0);
48 break;
49 case CPU_DOWN_PREPARE:
50 smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1);
51 break;
52 }
53 return NOTIFY_DONE;
54}
55
56static struct notifier_block oprofile_cpu_nb = {
57 .notifier_call = oprofile_cpu_notifier
58};
59#endif
60
36#ifdef CONFIG_PM 61#ifdef CONFIG_PM
37 62
38static int nmi_suspend(struct sys_device *dev, pm_message_t state) 63static int nmi_suspend(struct sys_device *dev, pm_message_t state)
39{ 64{
65 /* Only one CPU left, just stop that one */
40 if (nmi_enabled == 1) 66 if (nmi_enabled == 1)
41 nmi_stop(); 67 nmi_cpu_stop(NULL);
42 return 0; 68 return 0;
43} 69}
44 70
45static int nmi_resume(struct sys_device *dev) 71static int nmi_resume(struct sys_device *dev)
46{ 72{
47 if (nmi_enabled == 1) 73 if (nmi_enabled == 1)
48 nmi_start(); 74 nmi_cpu_start(NULL);
49 return 0; 75 return 0;
50} 76}
51 77
@@ -468,6 +494,9 @@ int __init op_nmi_init(struct oprofile_operations *ops)
468 return -ENODEV; 494 return -ENODEV;
469 } 495 }
470 496
497#ifdef CONFIG_SMP
498 register_cpu_notifier(&oprofile_cpu_nb);
499#endif
471 /* default values, can be overwritten by model */ 500 /* default values, can be overwritten by model */
472 ops->create_files = nmi_create_files; 501 ops->create_files = nmi_create_files;
473 ops->setup = nmi_setup; 502 ops->setup = nmi_setup;
@@ -489,8 +518,12 @@ int __init op_nmi_init(struct oprofile_operations *ops)
489 518
490void op_nmi_exit(void) 519void op_nmi_exit(void)
491{ 520{
492 if (using_nmi) 521 if (using_nmi) {
493 exit_sysfs(); 522 exit_sysfs();
523#ifdef CONFIG_SMP
524 unregister_cpu_notifier(&oprofile_cpu_nb);
525#endif
526 }
494 if (model->exit) 527 if (model->exit)
495 model->exit(); 528 model->exit();
496} 529}