|
@@ -28,85 +28,9 @@ static struct op_x86_model_spec const *model;
|
|
static DEFINE_PER_CPU(struct op_msrs, cpu_msrs);
|
|
static DEFINE_PER_CPU(struct op_msrs, cpu_msrs);
|
|
static DEFINE_PER_CPU(unsigned long, saved_lvtpc);
|
|
static DEFINE_PER_CPU(unsigned long, saved_lvtpc);
|
|
|
|
|
|
-static int nmi_start(void);
|
|
|
|
-static void nmi_stop(void);
|
|
|
|
-static void nmi_cpu_start(void *dummy);
|
|
|
|
-static void nmi_cpu_stop(void *dummy);
|
|
|
|
-
|
|
|
|
/* 0 == registered but off, 1 == registered and on */
|
|
/* 0 == registered but off, 1 == registered and on */
|
|
static int nmi_enabled = 0;
|
|
static int nmi_enabled = 0;
|
|
|
|
|
|
-#ifdef CONFIG_SMP
|
|
|
|
-static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
|
|
|
|
- void *data)
|
|
|
|
-{
|
|
|
|
- int cpu = (unsigned long)data;
|
|
|
|
- switch (action) {
|
|
|
|
- case CPU_DOWN_FAILED:
|
|
|
|
- case CPU_ONLINE:
|
|
|
|
- smp_call_function_single(cpu, nmi_cpu_start, NULL, 0);
|
|
|
|
- break;
|
|
|
|
- case CPU_DOWN_PREPARE:
|
|
|
|
- smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- return NOTIFY_DONE;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static struct notifier_block oprofile_cpu_nb = {
|
|
|
|
- .notifier_call = oprofile_cpu_notifier
|
|
|
|
-};
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
-#ifdef CONFIG_PM
|
|
|
|
-
|
|
|
|
-static int nmi_suspend(struct sys_device *dev, pm_message_t state)
|
|
|
|
-{
|
|
|
|
- /* Only one CPU left, just stop that one */
|
|
|
|
- if (nmi_enabled == 1)
|
|
|
|
- nmi_cpu_stop(NULL);
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int nmi_resume(struct sys_device *dev)
|
|
|
|
-{
|
|
|
|
- if (nmi_enabled == 1)
|
|
|
|
- nmi_cpu_start(NULL);
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static struct sysdev_class oprofile_sysclass = {
|
|
|
|
- .name = "oprofile",
|
|
|
|
- .resume = nmi_resume,
|
|
|
|
- .suspend = nmi_suspend,
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-static struct sys_device device_oprofile = {
|
|
|
|
- .id = 0,
|
|
|
|
- .cls = &oprofile_sysclass,
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-static int __init init_sysfs(void)
|
|
|
|
-{
|
|
|
|
- int error;
|
|
|
|
-
|
|
|
|
- error = sysdev_class_register(&oprofile_sysclass);
|
|
|
|
- if (!error)
|
|
|
|
- error = sysdev_register(&device_oprofile);
|
|
|
|
- return error;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void exit_sysfs(void)
|
|
|
|
-{
|
|
|
|
- sysdev_unregister(&device_oprofile);
|
|
|
|
- sysdev_class_unregister(&oprofile_sysclass);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-#else
|
|
|
|
-#define init_sysfs() do { } while (0)
|
|
|
|
-#define exit_sysfs() do { } while (0)
|
|
|
|
-#endif /* CONFIG_PM */
|
|
|
|
-
|
|
|
|
static int profile_exceptions_notify(struct notifier_block *self,
|
|
static int profile_exceptions_notify(struct notifier_block *self,
|
|
unsigned long val, void *data)
|
|
unsigned long val, void *data)
|
|
{
|
|
{
|
|
@@ -361,6 +285,77 @@ static int nmi_create_files(struct super_block *sb, struct dentry *root)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef CONFIG_SMP
|
|
|
|
+static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
|
|
|
|
+ void *data)
|
|
|
|
+{
|
|
|
|
+ int cpu = (unsigned long)data;
|
|
|
|
+ switch (action) {
|
|
|
|
+ case CPU_DOWN_FAILED:
|
|
|
|
+ case CPU_ONLINE:
|
|
|
|
+ smp_call_function_single(cpu, nmi_cpu_start, NULL, 0);
|
|
|
|
+ break;
|
|
|
|
+ case CPU_DOWN_PREPARE:
|
|
|
|
+ smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ return NOTIFY_DONE;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static struct notifier_block oprofile_cpu_nb = {
|
|
|
|
+ .notifier_call = oprofile_cpu_notifier
|
|
|
|
+};
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_PM
|
|
|
|
+
|
|
|
|
+static int nmi_suspend(struct sys_device *dev, pm_message_t state)
|
|
|
|
+{
|
|
|
|
+ /* Only one CPU left, just stop that one */
|
|
|
|
+ if (nmi_enabled == 1)
|
|
|
|
+ nmi_cpu_stop(NULL);
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int nmi_resume(struct sys_device *dev)
|
|
|
|
+{
|
|
|
|
+ if (nmi_enabled == 1)
|
|
|
|
+ nmi_cpu_start(NULL);
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static struct sysdev_class oprofile_sysclass = {
|
|
|
|
+ .name = "oprofile",
|
|
|
|
+ .resume = nmi_resume,
|
|
|
|
+ .suspend = nmi_suspend,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct sys_device device_oprofile = {
|
|
|
|
+ .id = 0,
|
|
|
|
+ .cls = &oprofile_sysclass,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static int __init init_sysfs(void)
|
|
|
|
+{
|
|
|
|
+ int error;
|
|
|
|
+
|
|
|
|
+ error = sysdev_class_register(&oprofile_sysclass);
|
|
|
|
+ if (!error)
|
|
|
|
+ error = sysdev_register(&device_oprofile);
|
|
|
|
+ return error;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void exit_sysfs(void)
|
|
|
|
+{
|
|
|
|
+ sysdev_unregister(&device_oprofile);
|
|
|
|
+ sysdev_class_unregister(&oprofile_sysclass);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#else
|
|
|
|
+#define init_sysfs() do { } while (0)
|
|
|
|
+#define exit_sysfs() do { } while (0)
|
|
|
|
+#endif /* CONFIG_PM */
|
|
|
|
+
|
|
static int p4force;
|
|
static int p4force;
|
|
module_param(p4force, int, 0);
|
|
module_param(p4force, int, 0);
|
|
|
|
|