increase traffic on linux-kernel
Subsystems (3)
PATCH 4/4 increase traffic on linux-kernel
[This has four scalps already. Thomas Molina has agreed
to track things as they are identified ]
Infrastructure to detect sleep-inside-spinlock bugs. Really only useful if compiled with CONFIG_PREEMPT=y. It prints out a whiny message and a stack backtrace if someone calls a function which might sleep from within an atomic region.
This patch generates a storm of output at boot, due to drivers/ide/ide-probe.c:init_irq() calling lots of things which it shouldn't under ide_lock.
It'll find other bugs too.
include/asm-i386/semaphore.h | 4 ++-- include/linux/kernel.h | 7 +++++++ include/linux/rwsem.h | 2 ++ kernel/ksyms.c | 4 +++- kernel/sched.c | 17 +++++++++++++++++ mm/page_alloc.c | 3 +++ mm/slab.c | 3 +++ 7 files changed, 37 insertions(+), 3 deletions(-)
include/asm-i386/semaphore.h renamed from include/asm-i386/semaphore.h~might_sleep +2 -2
@@ -116,7 +116,7 @@ static inline void down(struct semaphore#if WAITQUEUE_DEBUG CHECK_MAGIC (sem->__magic);#endif - +might_sleep (); __asm__ __volatile__("# atomic down operation\n\t" LOCK "decl %0\n\t" /* --sem->count */
@@ -142,7 +142,7 @@ static inline int down_interruptible(str#if WAITQUEUE_DEBUG CHECK_MAGIC (sem->__magic);#endif - +might_sleep (); __asm__ __volatile__("# atomic interruptible down operation\n\t" LOCK "decl %1\n\t" /* --sem->count */
include/linux/kernel.h renamed from include/linux/kernel.h~might_sleep +7 -0
@@ -40,6 +40,13 @@struct completion ; +#ifdef CONFIG_DEBUG_KERNEL +void __might_sleep (char *file,int line); +#define might_sleep () __might_sleep(__FILE__, __LINE__) +#else +#define might_sleep () do {} while(0) +#endif +extern struct notifier_block *panic_notifier_list; NORET_TYPE void panic(const char * fmt, ...) __attribute__ ((NORET_AND format (printf, 1, 2)));
include/linux/rwsem.h renamed from include/linux/rwsem.h~might_sleep +2 -0
@@ -40,6 +40,7 @@ extern void FASTCALL(rwsemtrace(struct r*/ static inline void down_read (struct rw_semaphore *sem) { +might_sleep ();rwsemtrace (sem,"Entering down_read" );__down_read (sem);rwsemtrace (sem,"Leaving down_read" );
@@ -62,6 +63,7 @@ static inline int down_read_trylock(stru*/ static inline void down_write (struct rw_semaphore *sem) { +might_sleep ();rwsemtrace (sem,"Entering down_write" );__down_write (sem);rwsemtrace (sem,"Leaving down_write" );
kernel/ksyms.c renamed from kernel/ksyms.c~might_sleep +3 -1
@@ -497,7 +497,9 @@ EXPORT_SYMBOL(jiffies_64);EXPORT_SYMBOL (xtime);EXPORT_SYMBOL (do_gettimeofday);EXPORT_SYMBOL (do_settimeofday); - +#ifdef CONFIG_DEBUG_KERNEL +EXPORT_SYMBOL (__might_sleep); +#endif #if !defined(__ia64__)EXPORT_SYMBOL (loops_per_jiffy);#endif
kernel/sched.c renamed from kernel/sched.c~might_sleep +17 -0
@@ -2150,3 +2150,20 @@ void __init sched_init(void)enter_lazy_tlb (&init_mm, current,smp_processor_id ()); } +#ifdef CONFIG_DEBUG_KERNEL +void __might_sleep (char *file,int line) +{ +#if defined(in_atomic) +static unsigned long prev_jiffy;/* ratelimiting */ + +if (in_atomic ()) { +if (time_before (jiffies, prev_jiffy +HZ )) +return ; + prev_jiffy = jiffies; +printk ("Sleeping function called from illegal" +" context at %s:%d\n" , file, line); +dump_stack (); + } +#endif +} +#endif
mm/page_alloc.c renamed from mm/page_alloc.c~might_sleep +3 -0
@@ -321,6 +321,9 @@ __alloc_pages(unsigned int gfp_mask, unsstruct page * page;int freed, i; +if (gfp_mask & __GFP_WAIT) +might_sleep (); +KERNEL_STAT_ADD (pgalloc,1 <<order); zones = zonelist->zones;/* the list of zones suitable for gfp_mask */
mm/slab.c renamed from mm/slab.c~might_sleep +3 -0
@@ -1370,6 +1370,9 @@ static inline void * __kmem_cache_allocunsigned long save_flags;void * objp; +if (flags & __GFP_WAIT) +might_sleep (); +kmem_cache_alloc_head (cachep, flags); try_again:local_irq_save (save_flags);
.
include/linux/kernel.h line 48
Quoted 12 lines · Andrew Morton
include/linux/kernel.h renamed from include/linux/kernel.h~might_sleep +6
-0@@ -40,6 +40,13 @@struct completion ; +#ifdef CONFIG_DEBUG_KERNEL +void __might_sleep (char *file,int line); +#define might_sleep () __might_sleep(__FILE__, __LINE__) +#else +#define might_sleep () do {} while(0) +#endif
I disagree with this -- CONFIG_DEBUG_KERNEL should not enable any machinery.
Magic Sysrq should be enable-able without affecting any other parts of the kernel.
Quoted 8 lines · Jeff Garzik
Quoted 6 lines · Andrew Morton
include/linux/kernel.h Wed Sep 25 20:15:27 2002 renamed from include/linux/kernel.h~might_sleep Wed Sep 25 20:15:27 2002 +0
-0@@ -40,6 +40,13 @@ struct completion;
Quoted 8 lines
include/linux/kernel.h Wed Sep 25 20:15:27 2002 line 48
Quoted 6 lines
include/linux/kernel.h Wed Sep 25 20:15:27 2002 renamed from include/linux/kernel.h~might_sleep Wed Sep 25 20:15:27 2002 +6
-0+#ifdef CONFIG_DEBUG_KERNEL +void __might_sleep(char *file, int line); +#define might_sleep() __might_sleep(__FILE__, __LINE__) +#else +#define might_sleep() do {} while(0) +#endifI disagree with this --
CONFIG_DEBUG_KERNELshould not enable any machinery.
I did this because adding a function call to down() and friends has significant cost.
Quoted 2 lines
Magic Sysrq should be enable-able without affecting any other parts of the kernel.
A separate config option then?
Quoted 4 lines · Andrew Morton
Quoted 1 line · Jeff Garzik
I disagree with this --
CONFIG_DEBUG_KERNELshould not enable any machinery.A separate config option then?
please.
To answer your other email, moving magic-sysrq outside CONFIG_DEBUG_KERNEL should probably be done, though IMO that does not obviate the need for a separate config option here.
thanks,
Jeff
Quoted 4 lines · Jeff Garzik
...
Magic Sysrq should be enable-able without affecting any other parts of the kernel.
or move sysrq outside CONFIG_DEBUG_KERNEL?
Quoted 5 lines · Andrew Morton
Infrastructure to detect sleep-inside-spinlock bugs. Really only useful if compiled with
CONFIG_PREEMPT=y. It prints out a whiny message and a stack backtrace if someone calls a function which might sleep from within an atomic region.
Why not make this it's own config option, dependent on CONFIG_PREEMPT?
thanks,
greg k-h
Quoted 10 lines · Greg KH
Quoted 5 lines · Andrew Morton
Infrastructure to detect sleep-inside-spinlock bugs. Really only useful if compiled with
CONFIG_PREEMPT=y. It prints out a whiny message and a stack backtrace if someone calls a function which might sleep from within an atomic region.Why not make this it's own config option, dependent on
CONFIG_PREEMPT?
With CONFIG_PREEMPT=n, it'll detect might-sleep-inside-interrupt bugs.
Some value there I guess.
In article <[email protected]>,
Quoted 5 lines · Andrew Morton
Infrastructure to detect sleep-inside-spinlock bugs. Really only useful if compiled with
CONFIG_PREEMPT=y. It prints out a whiny message and a stack backtrace if someone calls a function which might sleep from within an atomic region.
This is in my BK tree now, along with Ingo's symbolic backtraces, which makes it possibly less tedious to read the output.
I would suggest that all developers for a while run with
CONFIG_PREEMPT=y
CONFIG_DEBUG_KERNEL=y
CONFIG_KALLSYMS=y
and see if something shows up in their subsystem (but be careful about the backtraces, since they often contain old crud, especially since gcc does a horrible job at keeping the stack together and thus leaves unused "holes" in the stack frame which then show old and stale info).
It shows clearly that at least the sound PCM code does locking completely the wrong way around, apparently at least partly because of bad abstraction macros that hide the fact that some locks are semaphores and others are spinlocks.
[ Rant: abstraction like this is _bad_, for christ sake! Don't hide what
locks you're using just to make the code look simpler. Hint: trying to do a "down()" within a spinlock is stupid and not produtive. ]
Thanks,
Linus
Em Fri, Sep 27, 2002 at 01:31:17AM +0000, Linus Torvalds escreveu:
Quoted 10 lines
In article <[email protected]>,
Quoted 4 lines · Andrew Morton
Infrastructure to detect sleep-inside-spinlock bugs. Really only useful if compiled with
CONFIG_PREEMPT=y. It prints out a whiny message and a stack backtrace if someone calls a function which might sleep from within an atomic region.This is in my BK tree now, along with Ingo's symbolic backtraces, which makes it possibly less tedious to read the output.
Wheee! Thanks a LOT for merging both. We'll have lots of fun with these ones while saving the old network protocols, that have lots of cases where we can see problems even without these tools, imagine with them in place 8)
- Arnaldo