aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/oprofile/nmi_int.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-23 13:05:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-23 13:05:40 -0400
commit92fb83afd6664a6f8a05f990d264c998f9b99f69 (patch)
treeb5c65f2a14d1019d8e00d94dafbc65696906455c /arch/x86/oprofile/nmi_int.c
parenta5344876065e047d507800d0801a637d68d3b129 (diff)
parentdf13b31c286b3e91c556167954eda088d90a4295 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile: (21 commits) OProfile: Fix buffer synchronization for IBS oprofile: hotplug cpu fix oprofile: fixing whitespaces in arch/x86/oprofile/* oprofile: fixing whitespaces in arch/x86/oprofile/* oprofile: fixing whitespaces in drivers/oprofile/* x86/oprofile: add the logic for enabling additional IBS bits x86/oprofile: reordering functions in nmi_int.c x86/oprofile: removing unused function parameter in add_ibs_begin() oprofile: more whitespace fixes oprofile: whitespace fixes OProfile: Rename IBS sysfs dir into "ibs_op" OProfile: Rework string handling in setup_ibs_files() OProfile: Rework oprofile_add_ibs_sample() function oprofile: discover counters for op ppro too oprofile: Implement Intel architectural perfmon support oprofile: Don't report Nehalem as core_2 oprofile: drop const in num counters field Revert "Oprofile Multiplexing Patch" x86, oprofile: BUG: using smp_processor_id() in preemptible code x86/oprofile: fix on_each_cpu build error ... Manually fixed trivial conflicts in drivers/oprofile/{cpu_buffer.c,event_buffer.h}
Diffstat (limited to 'arch/x86/oprofile/nmi_int.c')
-rw-r--r--arch/x86/oprofile/nmi_int.c173
1 files changed, 88 insertions, 85 deletions
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 57f6c9088081..022cd41ea9b4 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
@@ -420,9 +415,6 @@ static int __init ppro_init(char **cpu_type)
420 case 15: case 23: 415 case 15: case 23:
421 *cpu_type = "i386/core_2"; 416 *cpu_type = "i386/core_2";
422 break; 417 break;
423 case 26:
424 *cpu_type = "i386/core_2";
425 break;
426 default: 418 default:
427 /* Unknown */ 419 /* Unknown */
428 return 0; 420 return 0;
@@ -432,6 +424,16 @@ static int __init ppro_init(char **cpu_type)
432 return 1; 424 return 1;
433} 425}
434 426
427static int __init arch_perfmon_init(char **cpu_type)
428{
429 if (!cpu_has_arch_perfmon)
430 return 0;
431 *cpu_type = "i386/arch_perfmon";
432 model = &op_arch_perfmon_spec;
433 arch_perfmon_setup_counters();
434 return 1;
435}
436
435/* in order to get sysfs right */ 437/* in order to get sysfs right */
436static int using_nmi; 438static int using_nmi;
437 439
@@ -439,7 +441,7 @@ int __init op_nmi_init(struct oprofile_operations *ops)
439{ 441{
440 __u8 vendor = boot_cpu_data.x86_vendor; 442 __u8 vendor = boot_cpu_data.x86_vendor;
441 __u8 family = boot_cpu_data.x86; 443 __u8 family = boot_cpu_data.x86;
442 char *cpu_type; 444 char *cpu_type = NULL;
443 int ret = 0; 445 int ret = 0;
444 446
445 if (!cpu_has_apic) 447 if (!cpu_has_apic)
@@ -477,19 +479,20 @@ int __init op_nmi_init(struct oprofile_operations *ops)
477 switch (family) { 479 switch (family) {
478 /* Pentium IV */ 480 /* Pentium IV */
479 case 0xf: 481 case 0xf:
480 if (!p4_init(&cpu_type)) 482 p4_init(&cpu_type);
481 return -ENODEV;
482 break; 483 break;
483 484
484 /* A P6-class processor */ 485 /* A P6-class processor */
485 case 6: 486 case 6:
486 if (!ppro_init(&cpu_type)) 487 ppro_init(&cpu_type);
487 return -ENODEV;
488 break; 488 break;
489 489
490 default: 490 default:
491 return -ENODEV; 491 break;
492 } 492 }
493
494 if (!cpu_type && !arch_perfmon_init(&cpu_type))
495 return -ENODEV;
493 break; 496 break;
494 497
495 default: 498 default: