From 1c014f321e6d67f47504284701013f4c1eeba0b5 Mon Sep 17 00:00:00 2001 From: Syed Rameez Mustafa Date: Mon, 15 Jul 2013 11:52:09 -0700 Subject: [PATCH] kernel/lib: add additional debug capabilites for data corruption Data corruptions in the kernel often end up in system crashes that are easier to debug closer to the time of detection. Specifically, if we do not panic immediately after lock or list corruptions have been detected, the problem context is lost in the ensuing system mayhem. Add support for allowing system crash immediately after such corruptions are detected. The CONFIG option controls the enabling/disabling of the feature. Change-Id: I9b2eb62da506a13007acff63e85e9515145909ff Signed-off-by: Syed Rameez Mustafa --- include/linux/bug.h | 6 ++++++ kernel/workqueue.c | 2 ++ lib/Kconfig.debug | 7 +++++++ lib/list_debug.c | 9 ++++++++- lib/spinlock_debug.c | 2 ++ 5 files changed, 25 insertions(+), 1 deletion(-) diff --git a/include/linux/bug.h b/include/linux/bug.h index 72961c39576..cd141a4a085 100644 --- a/include/linux/bug.h +++ b/include/linux/bug.h @@ -96,4 +96,10 @@ static inline enum bug_trap_type report_bug(unsigned long bug_addr, } #endif /* CONFIG_GENERIC_BUG */ + +#ifdef CONFIG_PANIC_ON_DATA_CORRUPTION +#define PANIC_CORRUPTION 1 +#else +#define PANIC_CORRUPTION 0 +#endif /* CONFIG_PANIC_ON_DATA_CORRUPTION */ #endif /* _LINUX_BUG_H */ diff --git a/kernel/workqueue.c b/kernel/workqueue.c index f1a6e9e8e06..90fd57da8ea 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "workqueue_sched.h" @@ -1878,6 +1879,7 @@ __acquires(&gcwq->lock) printk(KERN_ERR " last function: "); print_symbol("%s\n", (unsigned long)f); debug_show_held_locks(current); + BUG_ON(PANIC_CORRUPTION); dump_stack(); } diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 097d70fa02d..b9060a1250c 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1290,6 +1290,13 @@ config ASYNC_RAID6_TEST If unsure, say N. +config PANIC_ON_DATA_CORRUPTION + bool "Cause a Kernel Panic When Data Corruption is detected" + help + Select this option to upgrade warnings for potentially + recoverable data corruption scenarios to system-halting panics, + for easier detection and debug. + source "samples/Kconfig" source "lib/Kconfig.kgdb" diff --git a/lib/list_debug.c b/lib/list_debug.c index 982b850d4e7..6a039a62841 100644 --- a/lib/list_debug.c +++ b/lib/list_debug.c @@ -10,6 +10,7 @@ #include #include #include +#include /* * Insert a new entry between two known consecutive entries. @@ -30,6 +31,10 @@ void __list_add(struct list_head *new, "list_add corruption. prev->next should be " "next (%p), but was %p. (prev=%p).\n", next, prev->next, prev); + + BUG_ON(((prev->next != next) || (next->prev != prev)) && + PANIC_CORRUPTION); + next->prev = new; new->next = next; new->prev = prev; @@ -55,8 +60,10 @@ void __list_del_entry(struct list_head *entry) "but was %p\n", entry, prev->next) || WARN(next->prev != entry, "list_del corruption. next->prev should be %p, " - "but was %p\n", entry, next->prev)) + "but was %p\n", entry, next->prev)) { + BUG_ON(PANIC_CORRUPTION); return; + } __list_del(prev, next); } diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index f2aa5de6f6c..ac516f4f59e 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c @@ -12,6 +12,7 @@ #include #include #include +#include void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name, struct lock_class_key *key) @@ -64,6 +65,7 @@ static void spin_dump(raw_spinlock_t *lock, const char *msg) owner ? owner->comm : "", owner ? task_pid_nr(owner) : -1, lock->owner_cpu); + BUG_ON(PANIC_CORRUPTION); dump_stack(); }