diff options
author | Andrey Ryabinin <a.ryabinin@samsung.com> | 2015-04-16 22:48:10 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-17 16:04:08 +0300 |
commit | 9d796e66230205cd3366f5660387bd9ecca9d336 (patch) | |
tree | 579863a7da34c7588874c44e951d8309089dad94 | |
parent | 230633d109e35b0a24277498e773edeb79b4a331 (diff) | |
download | linux-9d796e66230205cd3366f5660387bd9ecca9d336.tar.xz |
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 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/sched.h> #include "gcov.h" static int gcov_events_enabled; @@ -107,8 +108,10 @@ void gcov_enable_events(void) gcov_events_enabled = 1; /* Perform event callback for previously registered entries. */ - while ((info = gcov_info_next(info))) + while ((info = gcov_info_next(info))) { gcov_event(GCOV_ADD, info); + cond_resched(); + } mutex_unlock(&gcov_lock); } |