aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/oprofile
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/oprofile')
-rw-r--r--arch/x86/oprofile/nmi_int.c147
1 files changed, 71 insertions, 76 deletions
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 57f6c9088081..370d832f398d 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -28,85 +28,9 @@ static struct op_x86_model_spec const *model;
28static DEFINE_PER_CPU(struct op_msrs, cpu_msrs); 28static DEFINE_PER_CPU(struct op_msrs, cpu_msrs);
29static DEFINE_PER_CPU(unsigned long, saved_lvtpc); 29static DEFINE_PER_CPU(unsigned long, saved_lvtpc);
30 30
31static int nmi_start(void);
32static void nmi_stop(void);
33static void nmi_cpu_start(void *dummy);
34static void nmi_cpu_stop(void *dummy);
35
36/* 0 == registered but off, 1 == registered and on */ 31/* 0 == registered but off, 1 == registered and on */
37static int nmi_enabled = 0; 32static int nmi_enabled = 0;
38 33
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
61#ifdef CONFIG_PM
62
63static int nmi_suspend(struct sys_device *dev, pm_message_t state)
64{
65 /* Only one CPU left, just stop that one */
66 if (nmi_enabled == 1)
67 nmi_cpu_stop(NULL);
68 return 0;
69}
70
71static int nmi_resume(struct sys_device *dev)
72{
73 if (nmi_enabled == 1)
74 nmi_cpu_start(NULL);
75 return 0;
76}
77
78static struct sysdev_class oprofile_sysclass = {
79 .name = "oprofile",
80 .resume = nmi_resume,
81 .suspend = nmi_suspend,
82};
83
84static struct sys_device device_oprofile = {
85 .id = 0,
86 .cls = &oprofile_sysclass,
87};
88
89static int __init init_sysfs(void)
90{
91 int error;
92
93 error = sysdev_class_register(&oprofile_sysclass);
94 if (!error)
95 error = sysdev_register(&device_oprofile);
96 return error;
97}
98
99static void exit_sysfs(void)
100{
101 sysdev_unregister(&device_oprofile);
102 sysdev_class_unregister(&oprofile_sysclass);
103}
104
105#else
106#define init_sysfs() do { } while (0)
107#define exit_sysfs() do { } while (0)
108#endif /* CONFIG_PM */
109
110static int profile_exceptions_notify(struct notifier_block *self, 34static int profile_exceptions_notify(struct notifier_block *self,
111 unsigned long val, void *data) 35 unsigned long val, void *data)
112{ 36{
@@ -361,6 +285,77 @@ static int nmi_create_files(struct super_block *sb, struct dentry *root)
361 return 0; 285 return 0;
362} 286}
363 287
288#ifdef CONFIG_SMP
289static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
290 void *data)
291{
292 int cpu = (unsigned long)data;
293 switch (action) {
294 case CPU_DOWN_FAILED:
295 case CPU_ONLINE:
296 smp_call_function_single(cpu, nmi_cpu_start, NULL, 0);
297 break;
298 case CPU_DOWN_PREPARE:
299 smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1);
300 break;
301 }
302 return NOTIFY_DONE;
303}
304
305static struct notifier_block oprofile_cpu_nb = {
306 .notifier_call = oprofile_cpu_notifier
307};
308#endif
309
310#ifdef CONFIG_PM
311
312static int nmi_suspend(struct sys_device *dev, pm_message_t state)
313{
314 /* Only one CPU left, just stop that one */
315 if (nmi_enabled == 1)
316 nmi_cpu_stop(NULL);
317 return 0;
318}
319
320static int nmi_resume(struct sys_device *dev)
321{
322 if (nmi_enabled == 1)
323 nmi_cpu_start(NULL);
324 return 0;
325}
326
327static struct sysdev_class oprofile_sysclass = {
328 .name = "oprofile",
329 .resume = nmi_resume,
330 .suspend = nmi_suspend,
331};
332
333static struct sys_device device_oprofile = {
334 .id = 0,
335 .cls = &oprofile_sysclass,
336};
337
338static int __init init_sysfs(void)
339{
340 int error;
341
342 error = sysdev_class_register(&oprofile_sysclass);
343 if (!error)
344 error = sysdev_register(&device_oprofile);
345 return error;
346}
347
348static void exit_sysfs(void)
349{
350 sysdev_unregister(&device_oprofile);
351 sysdev_class_unregister(&oprofile_sysclass);
352}
353
354#else
355#define init_sysfs() do { } while (0)
356#define exit_sysfs() do { } while (0)
357#endif /* CONFIG_PM */
358
364static int p4force; 359static int p4force;
365module_param(p4force, int, 0); 360module_param(p4force, int, 0);
366 361