aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/oprofile/nmi_int.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2008-08-18 08:50:31 -0400
committerRobert Richter <robert.richter@amd.com>2008-10-13 13:25:09 -0400
commitb99170288421c79f0c2efa8b33e26e65f4bb7fb8 (patch)
tree7580ce405a4dbbd2c57fbc9a129102481467e281 /arch/x86/oprofile/nmi_int.c
parentf645f6406463a01869c50844befc76d528971690 (diff)
oprofile: Implement Intel architectural perfmon support
Newer Intel CPUs (Core1+) have support for architectural events described in CPUID 0xA. See the IA32 SDM Vol3b.18 for details. The advantage of this is that it can be done without knowing about the specific CPU, because the CPU describes by itself what performance events are supported. This is only a fallback because only a limited set of 6 events are supported. This allows to do profiling on Nehalem and on Atom systems (later not tested) This patch implements support for that in oprofile's Intel Family 6 profiling module. It also has the advantage of supporting an arbitary number of events now as reported by the CPU. Also allow arbitary counter widths >32bit while we're at it. Requires a patched oprofile userland to support the new architecture. v2: update for latest oprofile tree remove force_arch_perfmon Signed-off-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Robert Richter <robert.richter@amd.com>
Diffstat (limited to 'arch/x86/oprofile/nmi_int.c')
-rw-r--r--arch/x86/oprofile/nmi_int.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 1059f3fe6b1d..12d6f85084f1 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -429,6 +429,16 @@ static int __init ppro_init(char **cpu_type)
429 return 1; 429 return 1;
430} 430}
431 431
432static int __init arch_perfmon_init(char **cpu_type)
433{
434 if (!cpu_has_arch_perfmon)
435 return 0;
436 *cpu_type = "i386/arch_perfmon";
437 model = &op_arch_perfmon_spec;
438 arch_perfmon_setup_counters();
439 return 1;
440}
441
432/* in order to get sysfs right */ 442/* in order to get sysfs right */
433static int using_nmi; 443static int using_nmi;
434 444
@@ -436,7 +446,7 @@ int __init op_nmi_init(struct oprofile_operations *ops)
436{ 446{
437 __u8 vendor = boot_cpu_data.x86_vendor; 447 __u8 vendor = boot_cpu_data.x86_vendor;
438 __u8 family = boot_cpu_data.x86; 448 __u8 family = boot_cpu_data.x86;
439 char *cpu_type; 449 char *cpu_type = NULL;
440 int ret = 0; 450 int ret = 0;
441 451
442 if (!cpu_has_apic) 452 if (!cpu_has_apic)
@@ -474,19 +484,20 @@ int __init op_nmi_init(struct oprofile_operations *ops)
474 switch (family) { 484 switch (family) {
475 /* Pentium IV */ 485 /* Pentium IV */
476 case 0xf: 486 case 0xf:
477 if (!p4_init(&cpu_type)) 487 p4_init(&cpu_type);
478 return -ENODEV;
479 break; 488 break;
480 489
481 /* A P6-class processor */ 490 /* A P6-class processor */
482 case 6: 491 case 6:
483 if (!ppro_init(&cpu_type)) 492 ppro_init(&cpu_type);
484 return -ENODEV;
485 break; 493 break;
486 494
487 default: 495 default:
488 return -ENODEV; 496 break;
489 } 497 }
498
499 if (!cpu_type && !arch_perfmon_init(&cpu_type))
500 return -ENODEV;
490 break; 501 break;
491 502
492 default: 503 default: