diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/kexec.c | 7 | ||||
-rw-r--r-- | kernel/power/console.c | 6 | ||||
-rw-r--r-- | kernel/power/disk.c | 22 | ||||
-rw-r--r-- | kernel/power/main.c | 8 | ||||
-rw-r--r-- | kernel/power/user.c | 8 | ||||
-rw-r--r-- | kernel/printk.c | 15 | ||||
-rw-r--r-- | kernel/trace/trace_hw_branches.c | 64 |
7 files changed, 85 insertions, 45 deletions
diff --git a/kernel/kexec.c b/kernel/kexec.c index 8a6d7b08864e..483899578259 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
@@ -1465,6 +1465,11 @@ int kernel_kexec(void) | |||
1465 | error = device_power_down(PMSG_FREEZE); | 1465 | error = device_power_down(PMSG_FREEZE); |
1466 | if (error) | 1466 | if (error) |
1467 | goto Enable_irqs; | 1467 | goto Enable_irqs; |
1468 | |||
1469 | /* Suspend system devices */ | ||
1470 | error = sysdev_suspend(PMSG_FREEZE); | ||
1471 | if (error) | ||
1472 | goto Power_up_devices; | ||
1468 | } else | 1473 | } else |
1469 | #endif | 1474 | #endif |
1470 | { | 1475 | { |
@@ -1477,6 +1482,8 @@ int kernel_kexec(void) | |||
1477 | 1482 | ||
1478 | #ifdef CONFIG_KEXEC_JUMP | 1483 | #ifdef CONFIG_KEXEC_JUMP |
1479 | if (kexec_image->preserve_context) { | 1484 | if (kexec_image->preserve_context) { |
1485 | sysdev_resume(); | ||
1486 | Power_up_devices: | ||
1480 | device_power_up(PMSG_RESTORE); | 1487 | device_power_up(PMSG_RESTORE); |
1481 | Enable_irqs: | 1488 | Enable_irqs: |
1482 | local_irq_enable(); | 1489 | local_irq_enable(); |
diff --git a/kernel/power/console.c b/kernel/power/console.c index b8628be2a465..a3961b205de7 100644 --- a/kernel/power/console.c +++ b/kernel/power/console.c | |||
@@ -78,6 +78,12 @@ void pm_restore_console(void) | |||
78 | } | 78 | } |
79 | set_console(orig_fgconsole); | 79 | set_console(orig_fgconsole); |
80 | release_console_sem(); | 80 | release_console_sem(); |
81 | |||
82 | if (vt_waitactive(orig_fgconsole)) { | ||
83 | pr_debug("Resume: Can't switch VCs."); | ||
84 | return; | ||
85 | } | ||
86 | |||
81 | kmsg_redirect = orig_kmsg; | 87 | kmsg_redirect = orig_kmsg; |
82 | } | 88 | } |
83 | #endif | 89 | #endif |
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 432ee575c9ee..4a4a206b1979 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
@@ -227,6 +227,12 @@ static int create_image(int platform_mode) | |||
227 | "aborting hibernation\n"); | 227 | "aborting hibernation\n"); |
228 | goto Enable_irqs; | 228 | goto Enable_irqs; |
229 | } | 229 | } |
230 | sysdev_suspend(PMSG_FREEZE); | ||
231 | if (error) { | ||
232 | printk(KERN_ERR "PM: Some devices failed to power down, " | ||
233 | "aborting hibernation\n"); | ||
234 | goto Power_up_devices; | ||
235 | } | ||
230 | 236 | ||
231 | if (hibernation_test(TEST_CORE)) | 237 | if (hibernation_test(TEST_CORE)) |
232 | goto Power_up; | 238 | goto Power_up; |
@@ -242,9 +248,11 @@ static int create_image(int platform_mode) | |||
242 | if (!in_suspend) | 248 | if (!in_suspend) |
243 | platform_leave(platform_mode); | 249 | platform_leave(platform_mode); |
244 | Power_up: | 250 | Power_up: |
251 | sysdev_resume(); | ||
245 | /* NOTE: device_power_up() is just a resume() for devices | 252 | /* NOTE: device_power_up() is just a resume() for devices |
246 | * that suspended with irqs off ... no overall powerup. | 253 | * that suspended with irqs off ... no overall powerup. |
247 | */ | 254 | */ |
255 | Power_up_devices: | ||
248 | device_power_up(in_suspend ? | 256 | device_power_up(in_suspend ? |
249 | (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); | 257 | (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); |
250 | Enable_irqs: | 258 | Enable_irqs: |
@@ -335,6 +343,7 @@ static int resume_target_kernel(void) | |||
335 | "aborting resume\n"); | 343 | "aborting resume\n"); |
336 | goto Enable_irqs; | 344 | goto Enable_irqs; |
337 | } | 345 | } |
346 | sysdev_suspend(PMSG_QUIESCE); | ||
338 | /* We'll ignore saved state, but this gets preempt count (etc) right */ | 347 | /* We'll ignore saved state, but this gets preempt count (etc) right */ |
339 | save_processor_state(); | 348 | save_processor_state(); |
340 | error = restore_highmem(); | 349 | error = restore_highmem(); |
@@ -357,6 +366,7 @@ static int resume_target_kernel(void) | |||
357 | swsusp_free(); | 366 | swsusp_free(); |
358 | restore_processor_state(); | 367 | restore_processor_state(); |
359 | touch_softlockup_watchdog(); | 368 | touch_softlockup_watchdog(); |
369 | sysdev_resume(); | ||
360 | device_power_up(PMSG_RECOVER); | 370 | device_power_up(PMSG_RECOVER); |
361 | Enable_irqs: | 371 | Enable_irqs: |
362 | local_irq_enable(); | 372 | local_irq_enable(); |
@@ -440,6 +450,7 @@ int hibernation_platform_enter(void) | |||
440 | local_irq_disable(); | 450 | local_irq_disable(); |
441 | error = device_power_down(PMSG_HIBERNATE); | 451 | error = device_power_down(PMSG_HIBERNATE); |
442 | if (!error) { | 452 | if (!error) { |
453 | sysdev_suspend(PMSG_HIBERNATE); | ||
443 | hibernation_ops->enter(); | 454 | hibernation_ops->enter(); |
444 | /* We should never get here */ | 455 | /* We should never get here */ |
445 | while (1); | 456 | while (1); |
@@ -595,6 +606,12 @@ static int software_resume(void) | |||
595 | unsigned int flags; | 606 | unsigned int flags; |
596 | 607 | ||
597 | /* | 608 | /* |
609 | * If the user said "noresume".. bail out early. | ||
610 | */ | ||
611 | if (noresume) | ||
612 | return 0; | ||
613 | |||
614 | /* | ||
598 | * name_to_dev_t() below takes a sysfs buffer mutex when sysfs | 615 | * name_to_dev_t() below takes a sysfs buffer mutex when sysfs |
599 | * is configured into the kernel. Since the regular hibernate | 616 | * is configured into the kernel. Since the regular hibernate |
600 | * trigger path is via sysfs which takes a buffer mutex before | 617 | * trigger path is via sysfs which takes a buffer mutex before |
@@ -610,6 +627,11 @@ static int software_resume(void) | |||
610 | mutex_unlock(&pm_mutex); | 627 | mutex_unlock(&pm_mutex); |
611 | return -ENOENT; | 628 | return -ENOENT; |
612 | } | 629 | } |
630 | /* | ||
631 | * Some device discovery might still be in progress; we need | ||
632 | * to wait for this to finish. | ||
633 | */ | ||
634 | wait_for_device_probe(); | ||
613 | swsusp_resume_device = name_to_dev_t(resume_file); | 635 | swsusp_resume_device = name_to_dev_t(resume_file); |
614 | pr_debug("PM: Resume from partition %s\n", resume_file); | 636 | pr_debug("PM: Resume from partition %s\n", resume_file); |
615 | } else { | 637 | } else { |
diff --git a/kernel/power/main.c b/kernel/power/main.c index b4d219016b6c..c9632f841f64 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
@@ -298,8 +298,12 @@ static int suspend_enter(suspend_state_t state) | |||
298 | goto Done; | 298 | goto Done; |
299 | } | 299 | } |
300 | 300 | ||
301 | if (!suspend_test(TEST_CORE)) | 301 | error = sysdev_suspend(PMSG_SUSPEND); |
302 | error = suspend_ops->enter(state); | 302 | if (!error) { |
303 | if (!suspend_test(TEST_CORE)) | ||
304 | error = suspend_ops->enter(state); | ||
305 | sysdev_resume(); | ||
306 | } | ||
303 | 307 | ||
304 | device_power_up(PMSG_RESUME); | 308 | device_power_up(PMSG_RESUME); |
305 | Done: | 309 | Done: |
diff --git a/kernel/power/user.c b/kernel/power/user.c index 005b93d839ba..6c85359364f2 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
@@ -95,15 +95,15 @@ static int snapshot_open(struct inode *inode, struct file *filp) | |||
95 | data->swap = swsusp_resume_device ? | 95 | data->swap = swsusp_resume_device ? |
96 | swap_type_of(swsusp_resume_device, 0, NULL) : -1; | 96 | swap_type_of(swsusp_resume_device, 0, NULL) : -1; |
97 | data->mode = O_RDONLY; | 97 | data->mode = O_RDONLY; |
98 | error = pm_notifier_call_chain(PM_RESTORE_PREPARE); | 98 | error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); |
99 | if (error) | 99 | if (error) |
100 | pm_notifier_call_chain(PM_POST_RESTORE); | 100 | pm_notifier_call_chain(PM_POST_HIBERNATION); |
101 | } else { | 101 | } else { |
102 | data->swap = -1; | 102 | data->swap = -1; |
103 | data->mode = O_WRONLY; | 103 | data->mode = O_WRONLY; |
104 | error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); | 104 | error = pm_notifier_call_chain(PM_RESTORE_PREPARE); |
105 | if (error) | 105 | if (error) |
106 | pm_notifier_call_chain(PM_POST_HIBERNATION); | 106 | pm_notifier_call_chain(PM_POST_RESTORE); |
107 | } | 107 | } |
108 | if (error) | 108 | if (error) |
109 | atomic_inc(&snapshot_device_available); | 109 | atomic_inc(&snapshot_device_available); |
diff --git a/kernel/printk.c b/kernel/printk.c index 69188f226a93..e3602d0755b0 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -73,7 +73,6 @@ EXPORT_SYMBOL(oops_in_progress); | |||
73 | * driver system. | 73 | * driver system. |
74 | */ | 74 | */ |
75 | static DECLARE_MUTEX(console_sem); | 75 | static DECLARE_MUTEX(console_sem); |
76 | static DECLARE_MUTEX(secondary_console_sem); | ||
77 | struct console *console_drivers; | 76 | struct console *console_drivers; |
78 | EXPORT_SYMBOL_GPL(console_drivers); | 77 | EXPORT_SYMBOL_GPL(console_drivers); |
79 | 78 | ||
@@ -891,12 +890,14 @@ void suspend_console(void) | |||
891 | printk("Suspending console(s) (use no_console_suspend to debug)\n"); | 890 | printk("Suspending console(s) (use no_console_suspend to debug)\n"); |
892 | acquire_console_sem(); | 891 | acquire_console_sem(); |
893 | console_suspended = 1; | 892 | console_suspended = 1; |
893 | up(&console_sem); | ||
894 | } | 894 | } |
895 | 895 | ||
896 | void resume_console(void) | 896 | void resume_console(void) |
897 | { | 897 | { |
898 | if (!console_suspend_enabled) | 898 | if (!console_suspend_enabled) |
899 | return; | 899 | return; |
900 | down(&console_sem); | ||
900 | console_suspended = 0; | 901 | console_suspended = 0; |
901 | release_console_sem(); | 902 | release_console_sem(); |
902 | } | 903 | } |
@@ -912,11 +913,9 @@ void resume_console(void) | |||
912 | void acquire_console_sem(void) | 913 | void acquire_console_sem(void) |
913 | { | 914 | { |
914 | BUG_ON(in_interrupt()); | 915 | BUG_ON(in_interrupt()); |
915 | if (console_suspended) { | ||
916 | down(&secondary_console_sem); | ||
917 | return; | ||
918 | } | ||
919 | down(&console_sem); | 916 | down(&console_sem); |
917 | if (console_suspended) | ||
918 | return; | ||
920 | console_locked = 1; | 919 | console_locked = 1; |
921 | console_may_schedule = 1; | 920 | console_may_schedule = 1; |
922 | } | 921 | } |
@@ -926,6 +925,10 @@ int try_acquire_console_sem(void) | |||
926 | { | 925 | { |
927 | if (down_trylock(&console_sem)) | 926 | if (down_trylock(&console_sem)) |
928 | return -1; | 927 | return -1; |
928 | if (console_suspended) { | ||
929 | up(&console_sem); | ||
930 | return -1; | ||
931 | } | ||
929 | console_locked = 1; | 932 | console_locked = 1; |
930 | console_may_schedule = 0; | 933 | console_may_schedule = 0; |
931 | return 0; | 934 | return 0; |
@@ -979,7 +982,7 @@ void release_console_sem(void) | |||
979 | unsigned wake_klogd = 0; | 982 | unsigned wake_klogd = 0; |
980 | 983 | ||
981 | if (console_suspended) { | 984 | if (console_suspended) { |
982 | up(&secondary_console_sem); | 985 | up(&console_sem); |
983 | return; | 986 | return; |
984 | } | 987 | } |
985 | 988 | ||
diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c index 3561aace075c..7bfdf4c2347f 100644 --- a/kernel/trace/trace_hw_branches.c +++ b/kernel/trace/trace_hw_branches.c | |||
@@ -3,17 +3,15 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2008-2009 Intel Corporation. | 4 | * Copyright (C) 2008-2009 Intel Corporation. |
5 | * Markus Metzger <markus.t.metzger@gmail.com>, 2008-2009 | 5 | * Markus Metzger <markus.t.metzger@gmail.com>, 2008-2009 |
6 | * | ||
7 | */ | 6 | */ |
8 | 7 | #include <linux/spinlock.h> | |
9 | #include <linux/module.h> | 8 | #include <linux/kallsyms.h> |
10 | #include <linux/fs.h> | ||
11 | #include <linux/debugfs.h> | 9 | #include <linux/debugfs.h> |
12 | #include <linux/ftrace.h> | 10 | #include <linux/ftrace.h> |
13 | #include <linux/kallsyms.h> | 11 | #include <linux/module.h> |
14 | #include <linux/mutex.h> | ||
15 | #include <linux/cpu.h> | 12 | #include <linux/cpu.h> |
16 | #include <linux/smp.h> | 13 | #include <linux/smp.h> |
14 | #include <linux/fs.h> | ||
17 | 15 | ||
18 | #include <asm/ds.h> | 16 | #include <asm/ds.h> |
19 | 17 | ||
@@ -23,16 +21,17 @@ | |||
23 | 21 | ||
24 | #define SIZEOF_BTS (1 << 13) | 22 | #define SIZEOF_BTS (1 << 13) |
25 | 23 | ||
26 | /* The tracer mutex protects the below per-cpu tracer array. | 24 | /* |
27 | It needs to be held to: | 25 | * The tracer lock protects the below per-cpu tracer array. |
28 | - start tracing on all cpus | 26 | * It needs to be held to: |
29 | - stop tracing on all cpus | 27 | * - start tracing on all cpus |
30 | - start tracing on a single hotplug cpu | 28 | * - stop tracing on all cpus |
31 | - stop tracing on a single hotplug cpu | 29 | * - start tracing on a single hotplug cpu |
32 | - read the trace from all cpus | 30 | * - stop tracing on a single hotplug cpu |
33 | - read the trace from a single cpu | 31 | * - read the trace from all cpus |
34 | */ | 32 | * - read the trace from a single cpu |
35 | static DEFINE_MUTEX(bts_tracer_mutex); | 33 | */ |
34 | static DEFINE_SPINLOCK(bts_tracer_lock); | ||
36 | static DEFINE_PER_CPU(struct bts_tracer *, tracer); | 35 | static DEFINE_PER_CPU(struct bts_tracer *, tracer); |
37 | static DEFINE_PER_CPU(unsigned char[SIZEOF_BTS], buffer); | 36 | static DEFINE_PER_CPU(unsigned char[SIZEOF_BTS], buffer); |
38 | 37 | ||
@@ -47,7 +46,7 @@ static struct trace_array *hw_branch_trace __read_mostly; | |||
47 | * Start tracing on the current cpu. | 46 | * Start tracing on the current cpu. |
48 | * The argument is ignored. | 47 | * The argument is ignored. |
49 | * | 48 | * |
50 | * pre: bts_tracer_mutex must be locked. | 49 | * pre: bts_tracer_lock must be locked. |
51 | */ | 50 | */ |
52 | static void bts_trace_start_cpu(void *arg) | 51 | static void bts_trace_start_cpu(void *arg) |
53 | { | 52 | { |
@@ -66,19 +65,19 @@ static void bts_trace_start_cpu(void *arg) | |||
66 | 65 | ||
67 | static void bts_trace_start(struct trace_array *tr) | 66 | static void bts_trace_start(struct trace_array *tr) |
68 | { | 67 | { |
69 | mutex_lock(&bts_tracer_mutex); | 68 | spin_lock(&bts_tracer_lock); |
70 | 69 | ||
71 | on_each_cpu(bts_trace_start_cpu, NULL, 1); | 70 | on_each_cpu(bts_trace_start_cpu, NULL, 1); |
72 | trace_hw_branches_enabled = 1; | 71 | trace_hw_branches_enabled = 1; |
73 | 72 | ||
74 | mutex_unlock(&bts_tracer_mutex); | 73 | spin_unlock(&bts_tracer_lock); |
75 | } | 74 | } |
76 | 75 | ||
77 | /* | 76 | /* |
78 | * Stop tracing on the current cpu. | 77 | * Stop tracing on the current cpu. |
79 | * The argument is ignored. | 78 | * The argument is ignored. |
80 | * | 79 | * |
81 | * pre: bts_tracer_mutex must be locked. | 80 | * pre: bts_tracer_lock must be locked. |
82 | */ | 81 | */ |
83 | static void bts_trace_stop_cpu(void *arg) | 82 | static void bts_trace_stop_cpu(void *arg) |
84 | { | 83 | { |
@@ -90,12 +89,12 @@ static void bts_trace_stop_cpu(void *arg) | |||
90 | 89 | ||
91 | static void bts_trace_stop(struct trace_array *tr) | 90 | static void bts_trace_stop(struct trace_array *tr) |
92 | { | 91 | { |
93 | mutex_lock(&bts_tracer_mutex); | 92 | spin_lock(&bts_tracer_lock); |
94 | 93 | ||
95 | trace_hw_branches_enabled = 0; | 94 | trace_hw_branches_enabled = 0; |
96 | on_each_cpu(bts_trace_stop_cpu, NULL, 1); | 95 | on_each_cpu(bts_trace_stop_cpu, NULL, 1); |
97 | 96 | ||
98 | mutex_unlock(&bts_tracer_mutex); | 97 | spin_unlock(&bts_tracer_lock); |
99 | } | 98 | } |
100 | 99 | ||
101 | static int __cpuinit bts_hotcpu_handler(struct notifier_block *nfb, | 100 | static int __cpuinit bts_hotcpu_handler(struct notifier_block *nfb, |
@@ -103,7 +102,7 @@ static int __cpuinit bts_hotcpu_handler(struct notifier_block *nfb, | |||
103 | { | 102 | { |
104 | unsigned int cpu = (unsigned long)hcpu; | 103 | unsigned int cpu = (unsigned long)hcpu; |
105 | 104 | ||
106 | mutex_lock(&bts_tracer_mutex); | 105 | spin_lock(&bts_tracer_lock); |
107 | 106 | ||
108 | if (!trace_hw_branches_enabled) | 107 | if (!trace_hw_branches_enabled) |
109 | goto out; | 108 | goto out; |
@@ -119,7 +118,7 @@ static int __cpuinit bts_hotcpu_handler(struct notifier_block *nfb, | |||
119 | } | 118 | } |
120 | 119 | ||
121 | out: | 120 | out: |
122 | mutex_unlock(&bts_tracer_mutex); | 121 | spin_unlock(&bts_tracer_lock); |
123 | return NOTIFY_DONE; | 122 | return NOTIFY_DONE; |
124 | } | 123 | } |
125 | 124 | ||
@@ -127,20 +126,18 @@ static struct notifier_block bts_hotcpu_notifier __cpuinitdata = { | |||
127 | .notifier_call = bts_hotcpu_handler | 126 | .notifier_call = bts_hotcpu_handler |
128 | }; | 127 | }; |
129 | 128 | ||
130 | static int __cpuinit bts_trace_init(struct trace_array *tr) | 129 | static int bts_trace_init(struct trace_array *tr) |
131 | { | 130 | { |
132 | hw_branch_trace = tr; | 131 | hw_branch_trace = tr; |
133 | 132 | ||
134 | register_hotcpu_notifier(&bts_hotcpu_notifier); | ||
135 | bts_trace_start(tr); | 133 | bts_trace_start(tr); |
136 | 134 | ||
137 | return 0; | 135 | return 0; |
138 | } | 136 | } |
139 | 137 | ||
140 | static void __cpuinit bts_trace_reset(struct trace_array *tr) | 138 | static void bts_trace_reset(struct trace_array *tr) |
141 | { | 139 | { |
142 | bts_trace_stop(tr); | 140 | bts_trace_stop(tr); |
143 | unregister_hotcpu_notifier(&bts_hotcpu_notifier); | ||
144 | } | 141 | } |
145 | 142 | ||
146 | static void bts_trace_print_header(struct seq_file *m) | 143 | static void bts_trace_print_header(struct seq_file *m) |
@@ -227,7 +224,7 @@ static void trace_bts_at(const struct bts_trace *trace, void *at) | |||
227 | /* | 224 | /* |
228 | * Collect the trace on the current cpu and write it into the ftrace buffer. | 225 | * Collect the trace on the current cpu and write it into the ftrace buffer. |
229 | * | 226 | * |
230 | * pre: bts_tracer_mutex must be locked | 227 | * pre: bts_tracer_lock must be locked |
231 | */ | 228 | */ |
232 | static void trace_bts_cpu(void *arg) | 229 | static void trace_bts_cpu(void *arg) |
233 | { | 230 | { |
@@ -263,11 +260,11 @@ out: | |||
263 | 260 | ||
264 | static void trace_bts_prepare(struct trace_iterator *iter) | 261 | static void trace_bts_prepare(struct trace_iterator *iter) |
265 | { | 262 | { |
266 | mutex_lock(&bts_tracer_mutex); | 263 | spin_lock(&bts_tracer_lock); |
267 | 264 | ||
268 | on_each_cpu(trace_bts_cpu, iter->tr, 1); | 265 | on_each_cpu(trace_bts_cpu, iter->tr, 1); |
269 | 266 | ||
270 | mutex_unlock(&bts_tracer_mutex); | 267 | spin_unlock(&bts_tracer_lock); |
271 | } | 268 | } |
272 | 269 | ||
273 | static void trace_bts_close(struct trace_iterator *iter) | 270 | static void trace_bts_close(struct trace_iterator *iter) |
@@ -277,11 +274,11 @@ static void trace_bts_close(struct trace_iterator *iter) | |||
277 | 274 | ||
278 | void trace_hw_branch_oops(void) | 275 | void trace_hw_branch_oops(void) |
279 | { | 276 | { |
280 | mutex_lock(&bts_tracer_mutex); | 277 | spin_lock(&bts_tracer_lock); |
281 | 278 | ||
282 | trace_bts_cpu(hw_branch_trace); | 279 | trace_bts_cpu(hw_branch_trace); |
283 | 280 | ||
284 | mutex_unlock(&bts_tracer_mutex); | 281 | spin_unlock(&bts_tracer_lock); |
285 | } | 282 | } |
286 | 283 | ||
287 | struct tracer bts_tracer __read_mostly = | 284 | struct tracer bts_tracer __read_mostly = |
@@ -299,6 +296,7 @@ struct tracer bts_tracer __read_mostly = | |||
299 | 296 | ||
300 | __init static int init_bts_trace(void) | 297 | __init static int init_bts_trace(void) |
301 | { | 298 | { |
299 | register_hotcpu_notifier(&bts_hotcpu_notifier); | ||
302 | return register_tracer(&bts_tracer); | 300 | return register_tracer(&bts_tracer); |
303 | } | 301 | } |
304 | device_initcall(init_bts_trace); | 302 | device_initcall(init_bts_trace); |