diff options
author | Robert Richter <robert.richter@amd.com> | 2008-09-24 05:25:31 -0400 |
---|---|---|
committer | Robert Richter <robert.richter@amd.com> | 2008-09-24 05:25:31 -0400 |
commit | f78e80209cf143be49f268c340431ae9fa3abb74 (patch) | |
tree | 820fa64b688099dfdd93d27ba03252738ca5c7e2 /arch/x86/oprofile/nmi_int.c | |
parent | 4c168eaf7ea39f25a45a3d8c7eebc3fedb633a1d (diff) | |
parent | 24342c34a022ee90839873d91396045e12ef1090 (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.c | 39 |
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 | ||
30 | static int nmi_start(void); | 31 | static int nmi_start(void); |
31 | static void nmi_stop(void); | 32 | static void nmi_stop(void); |
33 | static void nmi_cpu_start(void *dummy); | ||
34 | static 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 */ |
34 | static int nmi_enabled = 0; | 37 | static int nmi_enabled = 0; |
35 | 38 | ||
39 | #ifdef CONFIG_SMP | ||
40 | static 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 | |||
56 | static 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 | ||
38 | static int nmi_suspend(struct sys_device *dev, pm_message_t state) | 63 | static 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 | ||
45 | static int nmi_resume(struct sys_device *dev) | 71 | static 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 | ||
490 | void op_nmi_exit(void) | 519 | void 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 | } |