diff options
author | Andrey Ryabinin <a.ryabinin@samsung.com> | 2015-04-16 15:48:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-17 09:04:08 -0400 |
commit | 9d796e66230205cd3366f5660387bd9ecca9d336 (patch) | |
tree | 579863a7da34c7588874c44e951d8309089dad94 | |
parent | 230633d109e35b0a24277498e773edeb79b4a331 (diff) |
gcov: fix softlockups
gcov profiling if enabled with other heavy compile-time instrumentation
like KASan could trigger following softlockups:
NMI watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [swapper/0:1]
Modules linked in:
irq event stamp: 22823276
hardirqs last enabled at (22823275): [<ffffffff86e8d10d>] mutex_lock_nested+0x7d9/0x930
hardirqs last disabled at (22823276): [<ffffffff86e9521d>] apic_timer_interrupt+0x6d/0x80
softirqs last enabled at (22823172): [<ffffffff811ed969>] __do_softirq+0x4db/0x729
softirqs last disabled at (22823167): [<ffffffff811edfcf>] irq_exit+0x7d/0x15b
CPU: 0 PID: 1 Comm: swapper/0 Tainted: G W 3.19.0-05245-gbb33326-dirty #3
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5.1-0-g8936dbb-20141113_115728-nilsson.home.kraxel.org 04/01/2014
task: ffff88006cba8000 ti: ffff88006cbb0000 task.ti: ffff88006cbb0000
RIP: kasan_mem_to_shadow+0x1e/0x1f
Call Trace:
strcmp+0x28/0x70
get_node_by_name+0x66/0x99
gcov_event+0x4f/0x69e
gcov_enable_events+0x54/0x7b
gcov_fs_init+0xf8/0x134
do_one_initcall+0x1b2/0x288
kernel_init_freeable+0x467/0x580
kernel_init+0x15/0x18b
ret_from_fork+0x7c/0xb0
Kernel panic - not syncing: softlockup: hung tasks
Fix this by sticking cond_resched() in gcov_enable_events().
Signed-off-by: Andrey Ryabinin <a.ryabinin@samsung.com>
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Cc: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | kernel/gcov/base.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/kernel/gcov/base.c b/kernel/gcov/base.c index b358a802fd18..a744098e4eb7 100644 --- a/kernel/gcov/base.c +++ b/kernel/gcov/base.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
21 | #include <linux/sched.h> | ||
21 | #include "gcov.h" | 22 | #include "gcov.h" |
22 | 23 | ||
23 | static int gcov_events_enabled; | 24 | static int gcov_events_enabled; |
@@ -107,8 +108,10 @@ void gcov_enable_events(void) | |||
107 | gcov_events_enabled = 1; | 108 | gcov_events_enabled = 1; |
108 | 109 | ||
109 | /* Perform event callback for previously registered entries. */ | 110 | /* Perform event callback for previously registered entries. */ |
110 | while ((info = gcov_info_next(info))) | 111 | while ((info = gcov_info_next(info))) { |
111 | gcov_event(GCOV_ADD, info); | 112 | gcov_event(GCOV_ADD, info); |
113 | cond_resched(); | ||
114 | } | ||
112 | 115 | ||
113 | mutex_unlock(&gcov_lock); | 116 | mutex_unlock(&gcov_lock); |
114 | } | 117 | } |