oprofile, x86: Add kernel parameter oprofile.cpu_type=timer
authorRobert Richter <robert.richter@amd.com>
Tue, 11 Oct 2011 17:39:16 +0000 (19:39 +0200)
committerRobert Richter <robert.richter@amd.com>
Fri, 4 Nov 2011 14:04:34 +0000 (15:04 +0100)
We need this to better test x86 NMI timer mode. Otherwise it is very
hard to setup systems with NMI timer enabled, but we have this e.g. in
virtual machine environments.

Signed-off-by: Robert Richter <robert.richter@amd.com>
Documentation/kernel-parameters.txt
arch/x86/oprofile/nmi_int.c

index 854ed5ca7e3f122f5ac808b462eb14b9ee6b1977..f7735a125f4b21cd1bb1758ba575dd4df531323e 100644 (file)
@@ -1848,6 +1848,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        arch_perfmon: [X86] Force use of architectural
                                perfmon on Intel CPUs instead of the
                                CPU specific event set.
+                       timer: [X86] Force use of architectural NMI
+                               timer mode (see also oprofile.timer
+                               for generic hr timer mode)
 
        oops=panic      Always panic on oopses. Default is to just kill the
                        process, but there is a small probability of
index 68894fdc034bc3cb01cd79b66ec995dadc7b7c67..7ca4d43e8988d87dad64994b15b9a42ee5d5443d 100644 (file)
@@ -613,24 +613,36 @@ static int __init p4_init(char **cpu_type)
        return 0;
 }
 
-static int force_arch_perfmon;
-static int force_cpu_type(const char *str, struct kernel_param *kp)
+enum __force_cpu_type {
+       reserved = 0,           /* do not force */
+       timer,
+       arch_perfmon,
+};
+
+static int force_cpu_type;
+
+static int set_cpu_type(const char *str, struct kernel_param *kp)
 {
-       if (!strcmp(str, "arch_perfmon")) {
-               force_arch_perfmon = 1;
+       if (!strcmp(str, "timer")) {
+               force_cpu_type = timer;
+               printk(KERN_INFO "oprofile: forcing NMI timer mode\n");
+       } else if (!strcmp(str, "arch_perfmon")) {
+               force_cpu_type = arch_perfmon;
                printk(KERN_INFO "oprofile: forcing architectural perfmon\n");
+       } else {
+               force_cpu_type = 0;
        }
 
        return 0;
 }
-module_param_call(cpu_type, force_cpu_type, NULL, NULL, 0);
+module_param_call(cpu_type, set_cpu_type, NULL, NULL, 0);
 
 static int __init ppro_init(char **cpu_type)
 {
        __u8 cpu_model = boot_cpu_data.x86_model;
        struct op_x86_model_spec *spec = &op_ppro_spec; /* default */
 
-       if (force_arch_perfmon && cpu_has_arch_perfmon)
+       if (force_cpu_type == arch_perfmon && cpu_has_arch_perfmon)
                return 0;
 
        /*
@@ -697,6 +709,9 @@ int __init op_nmi_init(struct oprofile_operations *ops)
        if (!cpu_has_apic)
                return -ENODEV;
 
+       if (force_cpu_type == timer)
+               return -ENODEV;
+
        switch (vendor) {
        case X86_VENDOR_AMD:
                /* Needs to be at least an Athlon (or hammer in 32bit mode) */