Generic Mutex Subsystem, mutex-debug-more.patch
Subsystems (6)
PATCH 7/15 Generic Mutex Subsystem, mutex-debug-more.patch
more mutex debugging: check for held locks during memory freeing, task exit, enable sysrq printouts, etc.
Signed-off-by Ingo Molnar <[email protected]>
----
arch/i386/mm/pageattr.c | 3 +++ drivers/char/sysrq.c | 19 +++++++++++++++++++ include/linux/mm.h | 11 +++++++++++ include/linux/sched.h | 11 +++++++++++ kernel/exit.c | 4 ++++ kernel/sched.c | 1 + lib/spinlock_debug.c | 18 ++++++++++-------- mm/page_alloc.c | 3 +++ mm/slab.c | 5 +++++ 9 files changed, 67 insertions(+), 8 deletions(-)
arch/i386/mm/pageattr.c +3 -0
@@ -207,6 +207,9 @@ void kernel_map_pages(struct page *page, {if (PageHighMem (page))return ; +if (!enable) +check_no_locks_freed (page_address (page),page_address (page+numpages)); +/* the return value is ignored - the calls cannot fail, * large pages are disabled at boot time. */
drivers/char/sysrq.c +19 -0
@@ -153,6 +153,21 @@ static struct sysrq_key_op sysrq_mountro/* END SYNC SYSRQ HANDLERS BLOCK */ +#ifdef CONFIG_DEBUG_MUTEXESS + +static void +sysrq_handle_showlocks (int key,struct pt_regs *pt_regs,struct tty_struct *tty) +{ +show_all_locks (); +} + +static struct sysrq_key_op sysrq_showlocks_op = { + .handler = sysrq_handle_showlocks, + .help_msg ="show-all-locks(D)" , + .action_msg ="Show Locks Held" , +}; + +#endif /* SHOW SYSRQ HANDLERS BLOCK */
@@ -294,7 +309,11 @@ static struct sysrq_key_op *sysrq_key_ta#else /* c */ NULL,#endif +#ifdef CONFIG_DEBUG_MUTEXESS +/* d */ &sysrq_showlocks_op, +#else/* d */ NULL , +#endif/* e */ &sysrq_term_op,/* f */ &sysrq_moom_op, /* g */ NULL,
include/linux/mm.h +11 -0
@@ -973,10 +973,21 @@ static inline void vm_stat_account(struc }#endif /* CONFIG_PROC_FS */ +#ifdef CONFIG_DEBUG_MUTEXESS +extern int check_no_locks_freed (const void *from,const void *to); +#else +static inline int check_no_locks_freed (const void *from,const void *to) + { +return 0 ; + } +#endif +#ifndef CONFIG_DEBUG_PAGEALLOC static inline void kernel_map_pages (struct page *page,int numpages,int enable) { +if (!PageHighMem (page) && !enable) +check_no_locks_freed (page_address (page),page_address (page+numpages)); }#endif
include/linux/sched.h +11 -0
@@ -186,6 +186,17 @@ extern cpumask_t nohz_cpu_mask;extern void show_state (void );extern void show_regs (struct pt_regs *); +#ifdef CONFIG_DEBUG_MUTEXESS +extern void deadlock_trace_off (void ); +extern void show_held_locks (struct task_struct *filter); +extern void check_no_held_locks (struct task_struct *task); +extern void show_all_locks (void ); +#else +# define deadlock_trace_off () do { } while (0) +# define show_held_locks (p) do { } while (0) +# define check_no_held_locks (task) do { } while (0) +# define show_all_locks () do { } while (0) +#endif /* * TASK is a pointer to the task whose backtrace we want to see (or NULL for current
kernel/exit.c +4 -0
@@ -870,6 +870,10 @@ fastcall NORET_TYPE void do_exit(long compol_free (tsk->mempolicy); tsk->mempolicy =NULL ;#endif +/* +* If DEBUG_MUTEXESS is on, make sure we are holding no locks: +*/ +check_no_held_locks (tsk);/* PF_DEAD causes final put_task_struct after we schedule. */ preempt_disable ();
kernel/sched.c +1 -0
@@ -4379,6 +4379,7 @@ void show_state(void) }while_each_thread (g, p);read_unlock (&tasklist_lock); +show_all_locks (); }/**
lib/spinlock_debug.c +10 -8
@@ -20,7 +20,8 @@ static void spin_bug(spinlock_t *lock, cif (lock->owner && lock->owner !=SPINLOCK_OWNER_INIT ) owner = lock->owner;printk ("BUG: spinlock %s on CPU#%d, %s/%d\n" , - msg,smp_processor_id (), current->comm, current->pid); + msg,raw_smp_processor_id (), + current->comm, current->pid); printk(" lock: %p, .magic: %08x, .owner: %s/%d, .owner_cpu: %d\n", lock, lock->magic, owner ? owner->comm : "<none>",
@@ -78,8 +79,8 @@ static void __spin_lock_debug(spinlock_tif (print_once) { print_once =0 ;printk ("BUG: spinlock lockup on CPU#%d, %s/%d, %p\n" , -smp_processor_id (), current->comm, current->pid, - lock); +raw_smp_processor_id (), current->comm, + current->pid, lock);dump_stack (); } }
@@ -120,7 +121,8 @@ static void rwlock_bug(rwlock_t *lock, cif (xchg (&print_once,0 )) {printk ("BUG: rwlock %s on CPU#%d, %s/%d, %p\n" , msg, -smp_processor_id (), current->comm, current->pid, lock); +raw_smp_processor_id (), current->comm, + current->pid, lock);dump_stack ();#ifdef CONFIG_SMP /*
@@ -148,8 +150,8 @@ static void __read_lock_debug(rwlock_t *if (print_once) { print_once =0 ;printk ("BUG: read-lock lockup on CPU#%d, %s/%d, %p\n" , -smp_processor_id (), current->comm, current->pid, - lock); +raw_smp_processor_id (), current->comm, + current->pid, lock);dump_stack (); } }
@@ -220,8 +222,8 @@ static void __write_lock_debug(rwlock_tif (print_once) { print_once =0 ;printk ("BUG: write-lock lockup on CPU#%d, %s/%d, %p\n" , -smp_processor_id (), current->comm, current->pid, - lock); +raw_smp_processor_id (), current->comm, + current->pid, lock);dump_stack (); } }
mm/page_alloc.c +3 -0
@@ -400,6 +400,9 @@ void __free_pages_ok(struct page *page,int reserved =0 ;arch_free_page (page, order); +if (!PageHighMem (page)) +check_no_locks_freed (page_address (page), +page_address (page+(1 <<order)));#ifndef CONFIG_MMU if (order >0 )
mm/slab.c +5 -0
@@ -3038,6 +3038,11 @@ void kfree(const void *objp)local_irq_save (flags);kfree_debugcheck (objp); c =page_get_cache (virt_to_page (objp)); +#ifdef CONFIG_DEADLOCK_DETECT +if (check_no_locks_freed (objp, objp+cache_size (c))) +printk ("slab %s[%p] (%d), obj: %p\n" , + c->name, c, c->objsize, objp); +#endif __cache_free (c, (void *)objp);local_irq_restore (flags); }
Steven Rostedt
reviewerQuoted 27 lines · Ingo Molnar
Index:
linux/lib/spinlock_debug.c
===================================================================lib/spinlock_debug.c +2
-1@@ -20,7 +20,8 @@ static void spin_bug(spinlock_t *lock, cif (lock->owner && lock->owner !=SPINLOCK_OWNER_INIT ) owner = lock->owner;printk ("BUG: spinlock %s on CPU#%d, %s/%d\n" , - msg,smp_processor_id (), current->comm, current->pid); + msg, raw_smp_processor_id(), + current->comm, current->pid); printk(" lock: %p, .magic: %08x, .owner: %s/% d, .owner_cpu: %d\n",lock, lock->magic, owner ? owner->comm : "<none>",lib/spinlock_debug.c +2
-2@@ -78,8 +79,8 @@ static void __spin_lock_debug(spinlock_tif (print_once) { print_once =0 ; printk("BUG: spinlock lockup on CPU#%d, %s/%d, %p\n", - smp_processor_id(), current->comm, current->pid, - lock); +raw_smp_processor_id (), current->comm, + current->pid, lock);dump_stack ();
Quoted 2 lines
}
}The changes here from smp_processor_id to raw_smp_processor_id seem to be more clean up and not part of the mutex patch. Should these be sent separately?
-- Steve
Quoted 3 lines · Steven Rostedt
The changes here from
smp_processor_idtoraw_smp_processor_idseem to be more clean up and not part of the mutex patch. Should these be sent separately?
yeah, that's a bugfix for spinlock debugging, which should go in before 2.6.15 is released. Andrew/Linus, please apply.
Ingo