diff options
author | Ingo Molnar <mingo@elte.hu> | 2006-01-09 18:59:21 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@hera.kernel.org> | 2006-01-09 18:59:21 -0500 |
commit | de5097c2e73f826302cd8957c225b3725e0c7553 (patch) | |
tree | 3d56ab6fd891088ac55a9ef529faf4360391a22f | |
parent | 408894ee4dd4debfdedd472eb4d8414892fc90f6 (diff) |
[PATCH] mutex subsystem, more debugging code
more mutex debugging: check for held locks during memory freeing,
task exit, enable sysrq printouts, etc.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Arjan van de Ven <arjan@infradead.org>
-rw-r--r-- | arch/i386/mm/pageattr.c | 4 | ||||
-rw-r--r-- | drivers/char/sysrq.c | 19 | ||||
-rw-r--r-- | include/linux/mm.h | 4 | ||||
-rw-r--r-- | kernel/exit.c | 5 | ||||
-rw-r--r-- | kernel/sched.c | 1 | ||||
-rw-r--r-- | mm/page_alloc.c | 3 | ||||
-rw-r--r-- | mm/slab.c | 1 |
7 files changed, 37 insertions, 0 deletions
diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c index c30a16df6440..e8a53552b13d 100644 --- a/arch/i386/mm/pageattr.c +++ b/arch/i386/mm/pageattr.c | |||
@@ -222,6 +222,10 @@ void kernel_map_pages(struct page *page, int numpages, int enable) | |||
222 | { | 222 | { |
223 | if (PageHighMem(page)) | 223 | if (PageHighMem(page)) |
224 | return; | 224 | return; |
225 | if (!enable) | ||
226 | mutex_debug_check_no_locks_freed(page_address(page), | ||
227 | page_address(page+numpages)); | ||
228 | |||
225 | /* the return value is ignored - the calls cannot fail, | 229 | /* the return value is ignored - the calls cannot fail, |
226 | * large pages are disabled at boot time. | 230 | * large pages are disabled at boot time. |
227 | */ | 231 | */ |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 145275ebdd7e..5765f672e853 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -153,6 +153,21 @@ static struct sysrq_key_op sysrq_mountro_op = { | |||
153 | 153 | ||
154 | /* END SYNC SYSRQ HANDLERS BLOCK */ | 154 | /* END SYNC SYSRQ HANDLERS BLOCK */ |
155 | 155 | ||
156 | #ifdef CONFIG_DEBUG_MUTEXES | ||
157 | |||
158 | static void | ||
159 | sysrq_handle_showlocks(int key, struct pt_regs *pt_regs, struct tty_struct *tty) | ||
160 | { | ||
161 | mutex_debug_show_all_locks(); | ||
162 | } | ||
163 | |||
164 | static struct sysrq_key_op sysrq_showlocks_op = { | ||
165 | .handler = sysrq_handle_showlocks, | ||
166 | .help_msg = "show-all-locks(D)", | ||
167 | .action_msg = "Show Locks Held", | ||
168 | }; | ||
169 | |||
170 | #endif | ||
156 | 171 | ||
157 | /* SHOW SYSRQ HANDLERS BLOCK */ | 172 | /* SHOW SYSRQ HANDLERS BLOCK */ |
158 | 173 | ||
@@ -294,7 +309,11 @@ static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_LENGTH] = { | |||
294 | #else | 309 | #else |
295 | /* c */ NULL, | 310 | /* c */ NULL, |
296 | #endif | 311 | #endif |
312 | #ifdef CONFIG_DEBUG_MUTEXES | ||
313 | /* d */ &sysrq_showlocks_op, | ||
314 | #else | ||
297 | /* d */ NULL, | 315 | /* d */ NULL, |
316 | #endif | ||
298 | /* e */ &sysrq_term_op, | 317 | /* e */ &sysrq_term_op, |
299 | /* f */ &sysrq_moom_op, | 318 | /* f */ &sysrq_moom_op, |
300 | /* g */ NULL, | 319 | /* g */ NULL, |
diff --git a/include/linux/mm.h b/include/linux/mm.h index df80e63903b5..3f1fafc0245e 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/rbtree.h> | 13 | #include <linux/rbtree.h> |
14 | #include <linux/prio_tree.h> | 14 | #include <linux/prio_tree.h> |
15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
16 | #include <linux/mutex.h> | ||
16 | 17 | ||
17 | struct mempolicy; | 18 | struct mempolicy; |
18 | struct anon_vma; | 19 | struct anon_vma; |
@@ -1024,6 +1025,9 @@ static inline void vm_stat_account(struct mm_struct *mm, | |||
1024 | static inline void | 1025 | static inline void |
1025 | kernel_map_pages(struct page *page, int numpages, int enable) | 1026 | kernel_map_pages(struct page *page, int numpages, int enable) |
1026 | { | 1027 | { |
1028 | if (!PageHighMem(page) && !enable) | ||
1029 | mutex_debug_check_no_locks_freed(page_address(page), | ||
1030 | page_address(page + numpages)); | ||
1027 | } | 1031 | } |
1028 | #endif | 1032 | #endif |
1029 | 1033 | ||
diff --git a/kernel/exit.c b/kernel/exit.c index caceabf3f230..309a46fa16f8 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/syscalls.h> | 29 | #include <linux/syscalls.h> |
30 | #include <linux/signal.h> | 30 | #include <linux/signal.h> |
31 | #include <linux/cn_proc.h> | 31 | #include <linux/cn_proc.h> |
32 | #include <linux/mutex.h> | ||
32 | 33 | ||
33 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
34 | #include <asm/unistd.h> | 35 | #include <asm/unistd.h> |
@@ -869,6 +870,10 @@ fastcall NORET_TYPE void do_exit(long code) | |||
869 | mpol_free(tsk->mempolicy); | 870 | mpol_free(tsk->mempolicy); |
870 | tsk->mempolicy = NULL; | 871 | tsk->mempolicy = NULL; |
871 | #endif | 872 | #endif |
873 | /* | ||
874 | * If DEBUG_MUTEXES is on, make sure we are holding no locks: | ||
875 | */ | ||
876 | mutex_debug_check_no_locks_held(tsk); | ||
872 | 877 | ||
873 | /* PF_DEAD causes final put_task_struct after we schedule. */ | 878 | /* PF_DEAD causes final put_task_struct after we schedule. */ |
874 | preempt_disable(); | 879 | preempt_disable(); |
diff --git a/kernel/sched.c b/kernel/sched.c index 92733091154c..34a945bcc022 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -4386,6 +4386,7 @@ void show_state(void) | |||
4386 | } while_each_thread(g, p); | 4386 | } while_each_thread(g, p); |
4387 | 4387 | ||
4388 | read_unlock(&tasklist_lock); | 4388 | read_unlock(&tasklist_lock); |
4389 | mutex_debug_show_all_locks(); | ||
4389 | } | 4390 | } |
4390 | 4391 | ||
4391 | /** | 4392 | /** |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index e0e84924171b..a5e6891f7bb6 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -415,6 +415,9 @@ static void __free_pages_ok(struct page *page, unsigned int order) | |||
415 | int reserved = 0; | 415 | int reserved = 0; |
416 | 416 | ||
417 | arch_free_page(page, order); | 417 | arch_free_page(page, order); |
418 | if (!PageHighMem(page)) | ||
419 | mutex_debug_check_no_locks_freed(page_address(page), | ||
420 | page_address(page+(1<<order))); | ||
418 | 421 | ||
419 | #ifndef CONFIG_MMU | 422 | #ifndef CONFIG_MMU |
420 | for (i = 1 ; i < (1 << order) ; ++i) | 423 | for (i = 1 ; i < (1 << order) ; ++i) |
@@ -3071,6 +3071,7 @@ void kfree(const void *objp) | |||
3071 | local_irq_save(flags); | 3071 | local_irq_save(flags); |
3072 | kfree_debugcheck(objp); | 3072 | kfree_debugcheck(objp); |
3073 | c = page_get_cache(virt_to_page(objp)); | 3073 | c = page_get_cache(virt_to_page(objp)); |
3074 | mutex_debug_check_no_locks_freed(objp, objp+obj_reallen(c)); | ||
3074 | __cache_free(c, (void *)objp); | 3075 | __cache_free(c, (void *)objp); |
3075 | local_irq_restore(flags); | 3076 | local_irq_restore(flags); |
3076 | } | 3077 | } |