diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 3 | ||||
-rw-r--r-- | arch/x86/oprofile/nmi_int.c | 27 |
2 files changed, 24 insertions, 6 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 854ed5ca7e3f..f7735a125f4b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1848,6 +1848,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1848 | arch_perfmon: [X86] Force use of architectural | 1848 | arch_perfmon: [X86] Force use of architectural |
1849 | perfmon on Intel CPUs instead of the | 1849 | perfmon on Intel CPUs instead of the |
1850 | CPU specific event set. | 1850 | CPU specific event set. |
1851 | timer: [X86] Force use of architectural NMI | ||
1852 | timer mode (see also oprofile.timer | ||
1853 | for generic hr timer mode) | ||
1851 | 1854 | ||
1852 | oops=panic Always panic on oopses. Default is to just kill the | 1855 | oops=panic Always panic on oopses. Default is to just kill the |
1853 | process, but there is a small probability of | 1856 | process, but there is a small probability of |
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 68894fdc034b..7ca4d43e8988 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
@@ -613,24 +613,36 @@ static int __init p4_init(char **cpu_type) | |||
613 | return 0; | 613 | return 0; |
614 | } | 614 | } |
615 | 615 | ||
616 | static int force_arch_perfmon; | 616 | enum __force_cpu_type { |
617 | static int force_cpu_type(const char *str, struct kernel_param *kp) | 617 | reserved = 0, /* do not force */ |
618 | timer, | ||
619 | arch_perfmon, | ||
620 | }; | ||
621 | |||
622 | static int force_cpu_type; | ||
623 | |||
624 | static int set_cpu_type(const char *str, struct kernel_param *kp) | ||
618 | { | 625 | { |
619 | if (!strcmp(str, "arch_perfmon")) { | 626 | if (!strcmp(str, "timer")) { |
620 | force_arch_perfmon = 1; | 627 | force_cpu_type = timer; |
628 | printk(KERN_INFO "oprofile: forcing NMI timer mode\n"); | ||
629 | } else if (!strcmp(str, "arch_perfmon")) { | ||
630 | force_cpu_type = arch_perfmon; | ||
621 | printk(KERN_INFO "oprofile: forcing architectural perfmon\n"); | 631 | printk(KERN_INFO "oprofile: forcing architectural perfmon\n"); |
632 | } else { | ||
633 | force_cpu_type = 0; | ||
622 | } | 634 | } |
623 | 635 | ||
624 | return 0; | 636 | return 0; |
625 | } | 637 | } |
626 | module_param_call(cpu_type, force_cpu_type, NULL, NULL, 0); | 638 | module_param_call(cpu_type, set_cpu_type, NULL, NULL, 0); |
627 | 639 | ||
628 | static int __init ppro_init(char **cpu_type) | 640 | static int __init ppro_init(char **cpu_type) |
629 | { | 641 | { |
630 | __u8 cpu_model = boot_cpu_data.x86_model; | 642 | __u8 cpu_model = boot_cpu_data.x86_model; |
631 | struct op_x86_model_spec *spec = &op_ppro_spec; /* default */ | 643 | struct op_x86_model_spec *spec = &op_ppro_spec; /* default */ |
632 | 644 | ||
633 | if (force_arch_perfmon && cpu_has_arch_perfmon) | 645 | if (force_cpu_type == arch_perfmon && cpu_has_arch_perfmon) |
634 | return 0; | 646 | return 0; |
635 | 647 | ||
636 | /* | 648 | /* |
@@ -697,6 +709,9 @@ int __init op_nmi_init(struct oprofile_operations *ops) | |||
697 | if (!cpu_has_apic) | 709 | if (!cpu_has_apic) |
698 | return -ENODEV; | 710 | return -ENODEV; |
699 | 711 | ||
712 | if (force_cpu_type == timer) | ||
713 | return -ENODEV; | ||
714 | |||
700 | switch (vendor) { | 715 | switch (vendor) { |
701 | case X86_VENDOR_AMD: | 716 | case X86_VENDOR_AMD: |
702 | /* Needs to be at least an Athlon (or hammer in 32bit mode) */ | 717 | /* Needs to be at least an Athlon (or hammer in 32bit mode) */ |