From: Mitchell Blank Jr This patch makes the following improvements to might_sleep(): o Add a "might_sleep_if()" macro for when we might sleep only if some condition is met. It's a bit tidier, and has an unlikely() in it. o Add might_sleep checks to skb_share_check() and skb_unshare() which sometimes need to allocate memory. o Make all architectures call might_sleep() in both down() and down_interruptible(). Before only ppc, ppc64, and i386 did this check. (sh did the check on down() but not down_interruptible()) 25-akpm/arch/sparc64/kernel/semaphore.c | 2 ++ 25-akpm/include/asm-alpha/semaphore.h | 8 ++++++-- 25-akpm/include/asm-arm/semaphore.h | 4 ++-- 25-akpm/include/asm-arm26/semaphore.h | 4 ++-- 25-akpm/include/asm-cris/semaphore.h | 2 ++ 25-akpm/include/asm-h8300/semaphore.h | 2 ++ 25-akpm/include/asm-ia64/semaphore.h | 2 ++ 25-akpm/include/asm-m68k/semaphore.h | 4 ++-- 25-akpm/include/asm-m68knommu/semaphore.h | 4 ++-- 25-akpm/include/asm-mips/semaphore.h | 2 ++ 25-akpm/include/asm-parisc/semaphore.h | 4 ++-- 25-akpm/include/asm-s390/semaphore.h | 2 ++ 25-akpm/include/asm-sh/semaphore.h | 1 + 25-akpm/include/asm-sparc/semaphore.h | 2 ++ 25-akpm/include/asm-v850/semaphore.h | 2 ++ 25-akpm/include/asm-x86_64/semaphore.h | 2 ++ 25-akpm/include/linux/kernel.h | 2 ++ 25-akpm/include/linux/skbuff.h | 2 ++ 25-akpm/mm/page_alloc.c | 3 +-- 25-akpm/mm/rmap.c | 3 +-- 25-akpm/mm/slab.c | 3 +-- 21 files changed, 42 insertions(+), 18 deletions(-) diff -puN arch/sparc64/kernel/semaphore.c~might_sleep-improvements arch/sparc64/kernel/semaphore.c --- 25/arch/sparc64/kernel/semaphore.c~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/arch/sparc64/kernel/semaphore.c Tue Sep 2 08:19:47 2003 @@ -110,6 +110,7 @@ static void __down(struct semaphore * se void down(struct semaphore *sem) { + might_sleep(); /* This atomically does: * old_val = sem->count; * new_val = sem->count - 1; @@ -219,6 +220,7 @@ int down_interruptible(struct semaphore { int ret = 0; + might_sleep(); /* This atomically does: * old_val = sem->count; * new_val = sem->count - 1; diff -puN include/asm-alpha/semaphore.h~might_sleep-improvements include/asm-alpha/semaphore.h --- 25/include/asm-alpha/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-alpha/semaphore.h Tue Sep 2 08:19:47 2003 @@ -88,14 +88,18 @@ extern void __up_wakeup(struct semaphore static inline void __down(struct semaphore *sem) { - long count = atomic_dec_return(&sem->count); + long count; + might_sleep(); + count = atomic_dec_return(&sem->count); if (unlikely(count < 0)) __down_failed(sem); } static inline int __down_interruptible(struct semaphore *sem) { - long count = atomic_dec_return(&sem->count); + long count; + might_sleep(); + count = atomic_dec_return(&sem->count); if (unlikely(count < 0)) return __down_failed_interruptible(sem); return 0; diff -puN include/asm-arm26/semaphore.h~might_sleep-improvements include/asm-arm26/semaphore.h --- 25/include/asm-arm26/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-arm26/semaphore.h Tue Sep 2 08:19:47 2003 @@ -84,7 +84,7 @@ static inline void down(struct semaphore #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); __down_op(sem, __down_failed); } @@ -97,7 +97,7 @@ static inline int down_interruptible (st #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); return __down_op_ret(sem, __down_interruptible_failed); } diff -puN include/asm-arm/semaphore.h~might_sleep-improvements include/asm-arm/semaphore.h --- 25/include/asm-arm/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-arm/semaphore.h Tue Sep 2 08:19:47 2003 @@ -88,7 +88,7 @@ static inline void down(struct semaphore #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); __down_op(sem, __down_failed); } @@ -101,7 +101,7 @@ static inline int down_interruptible (st #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); return __down_op_ret(sem, __down_interruptible_failed); } diff -puN include/asm-cris/semaphore.h~might_sleep-improvements include/asm-cris/semaphore.h --- 25/include/asm-cris/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-cris/semaphore.h Tue Sep 2 08:19:47 2003 @@ -79,6 +79,7 @@ extern inline void down(struct semaphore #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); /* atomically decrement the semaphores count, and if its negative, we wait */ local_save_flags(flags); @@ -104,6 +105,7 @@ extern inline int down_interruptible(str #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); /* atomically decrement the semaphores count, and if its negative, we wait */ local_save_flags(flags); diff -puN include/asm-h8300/semaphore.h~might_sleep-improvements include/asm-h8300/semaphore.h --- 25/include/asm-h8300/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-h8300/semaphore.h Tue Sep 2 08:19:47 2003 @@ -90,6 +90,7 @@ static inline void down(struct semaphore #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); count = &(sem->count); __asm__ __volatile__( @@ -117,6 +118,7 @@ static inline int down_interruptible(str #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); count = &(sem->count); __asm__ __volatile__( diff -puN include/asm-ia64/semaphore.h~might_sleep-improvements include/asm-ia64/semaphore.h --- 25/include/asm-ia64/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-ia64/semaphore.h Tue Sep 2 08:19:47 2003 @@ -73,6 +73,7 @@ down (struct semaphore *sem) #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); if (atomic_dec_return(&sem->count) < 0) __down(sem); } @@ -89,6 +90,7 @@ down_interruptible (struct semaphore * s #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); if (atomic_dec_return(&sem->count) < 0) ret = __down_interruptible(sem); return ret; diff -puN include/asm-m68knommu/semaphore.h~might_sleep-improvements include/asm-m68knommu/semaphore.h --- 25/include/asm-m68knommu/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-m68knommu/semaphore.h Tue Sep 2 08:19:47 2003 @@ -88,7 +88,7 @@ extern inline void down(struct semaphore #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); __asm__ __volatile__( "| atomic down operation\n\t" "movel %0, %%a1\n\t" @@ -108,7 +108,7 @@ extern inline int down_interruptible(str #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); __asm__ __volatile__( "| atomic down operation\n\t" "movel %1, %%a1\n\t" diff -puN include/asm-m68k/semaphore.h~might_sleep-improvements include/asm-m68k/semaphore.h --- 25/include/asm-m68k/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-m68k/semaphore.h Tue Sep 2 08:19:47 2003 @@ -89,7 +89,7 @@ extern inline void down(struct semaphore #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); __asm__ __volatile__( "| atomic down operation\n\t" "subql #1,%0@\n\t" @@ -112,7 +112,7 @@ extern inline int down_interruptible(str #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); __asm__ __volatile__( "| atomic interruptible down operation\n\t" "subql #1,%1@\n\t" diff -puN include/asm-mips/semaphore.h~might_sleep-improvements include/asm-mips/semaphore.h --- 25/include/asm-mips/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-mips/semaphore.h Tue Sep 2 08:19:47 2003 @@ -88,6 +88,7 @@ static inline void down(struct semaphore #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); if (atomic_dec_return(&sem->count) < 0) __down(sem); } @@ -103,6 +104,7 @@ static inline int down_interruptible(str #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); if (atomic_dec_return(&sem->count) < 0) ret = __down_interruptible(sem); return ret; diff -puN include/asm-parisc/semaphore.h~might_sleep-improvements include/asm-parisc/semaphore.h --- 25/include/asm-parisc/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-parisc/semaphore.h Tue Sep 2 08:19:47 2003 @@ -84,7 +84,7 @@ extern __inline__ void down(struct semap #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); spin_lock_irq(&sem->sentry); if (sem->count > 0) { sem->count--; @@ -100,7 +100,7 @@ extern __inline__ int down_interruptible #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif - + might_sleep(); spin_lock_irq(&sem->sentry); if (sem->count > 0) { sem->count--; diff -puN include/asm-s390/semaphore.h~might_sleep-improvements include/asm-s390/semaphore.h --- 25/include/asm-s390/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-s390/semaphore.h Tue Sep 2 08:19:47 2003 @@ -60,6 +60,7 @@ asmlinkage void __up(struct semaphore * static inline void down(struct semaphore * sem) { + might_sleep(); if (atomic_dec_return(&sem->count) < 0) __down(sem); } @@ -68,6 +69,7 @@ static inline int down_interruptible(str { int ret = 0; + might_sleep(); if (atomic_dec_return(&sem->count) < 0) ret = __down_interruptible(sem); return ret; diff -puN include/asm-sh/semaphore.h~might_sleep-improvements include/asm-sh/semaphore.h --- 25/include/asm-sh/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-sh/semaphore.h Tue Sep 2 08:19:47 2003 @@ -107,6 +107,7 @@ static inline int down_interruptible(str CHECK_MAGIC(sem->__magic); #endif + might_sleep(); if (atomic_dec_return(&sem->count) < 0) ret = __down_interruptible(sem); return ret; diff -puN include/asm-sparc/semaphore.h~might_sleep-improvements include/asm-sparc/semaphore.h --- 25/include/asm-sparc/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-sparc/semaphore.h Tue Sep 2 08:19:47 2003 @@ -71,6 +71,7 @@ static inline void down(struct semaphore #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); ptr = &(sem->count.counter); increment = 1; @@ -107,6 +108,7 @@ static inline int down_interruptible(str #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); ptr = &(sem->count.counter); increment = 1; diff -puN include/asm-v850/semaphore.h~might_sleep-improvements include/asm-v850/semaphore.h --- 25/include/asm-v850/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-v850/semaphore.h Tue Sep 2 08:19:47 2003 @@ -57,6 +57,7 @@ extern void __up (struct semaphore * sem extern inline void down (struct semaphore * sem) { + might_sleep(); if (atomic_dec_return (&sem->count) < 0) __down (sem); } @@ -64,6 +65,7 @@ extern inline void down (struct semaphor extern inline int down_interruptible (struct semaphore * sem) { int ret = 0; + might_sleep(); if (atomic_dec_return (&sem->count) < 0) ret = __down_interruptible (sem); return ret; diff -puN include/asm-x86_64/semaphore.h~might_sleep-improvements include/asm-x86_64/semaphore.h --- 25/include/asm-x86_64/semaphore.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/asm-x86_64/semaphore.h Tue Sep 2 08:19:47 2003 @@ -118,6 +118,7 @@ static inline void down(struct semaphore #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); __asm__ __volatile__( "# atomic down operation\n\t" @@ -144,6 +145,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" diff -puN include/linux/kernel.h~might_sleep-improvements include/linux/kernel.h --- 25/include/linux/kernel.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/linux/kernel.h Tue Sep 2 08:19:47 2003 @@ -52,8 +52,10 @@ struct completion; #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP void __might_sleep(char *file, int line); #define might_sleep() __might_sleep(__FILE__, __LINE__) +#define might_sleep_if(cond) do { if (unlikely(cond)) might_sleep(); } while (0) #else #define might_sleep() do {} while(0) +#define might_sleep_if(cond) do {} while (0) #endif extern struct notifier_block *panic_notifier_list; diff -puN include/linux/skbuff.h~might_sleep-improvements include/linux/skbuff.h --- 25/include/linux/skbuff.h~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/include/linux/skbuff.h Tue Sep 2 08:19:47 2003 @@ -389,6 +389,7 @@ static inline int skb_shared(struct sk_b */ static inline struct sk_buff *skb_share_check(struct sk_buff *skb, int pri) { + might_sleep_if(pri & __GFP_WAIT); if (skb_shared(skb)) { struct sk_buff *nskb = skb_clone(skb, pri); kfree_skb(skb); @@ -419,6 +420,7 @@ static inline struct sk_buff *skb_share_ */ static inline struct sk_buff *skb_unshare(struct sk_buff *skb, int pri) { + might_sleep_if(pri & __GFP_WAIT); if (skb_cloned(skb)) { struct sk_buff *nskb = skb_copy(skb, pri); kfree_skb(skb); /* Free our shared copy */ diff -puN mm/page_alloc.c~might_sleep-improvements mm/page_alloc.c --- 25/mm/page_alloc.c~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/mm/page_alloc.c Tue Sep 2 08:19:47 2003 @@ -545,8 +545,7 @@ __alloc_pages(unsigned int gfp_mask, uns int cold; int do_retry; - if (wait) - might_sleep(); + might_sleep_if(wait); cold = 0; if (gfp_mask & __GFP_COLD) diff -puN mm/rmap.c~might_sleep-improvements mm/rmap.c --- 25/mm/rmap.c~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/mm/rmap.c Tue Sep 2 08:19:47 2003 @@ -503,8 +503,7 @@ struct pte_chain *pte_chain_alloc(int gf struct pte_chain *ret; struct pte_chain **pte_chainp; - if (gfp_flags & __GFP_WAIT) - might_sleep(); + might_sleep_if(gfp_flags & __GFP_WAIT); pte_chainp = &get_cpu_var(local_pte_chain); if (*pte_chainp) { diff -puN mm/slab.c~might_sleep-improvements mm/slab.c --- 25/mm/slab.c~might_sleep-improvements Tue Sep 2 08:19:47 2003 +++ 25-akpm/mm/slab.c Tue Sep 2 08:19:47 2003 @@ -1818,8 +1818,7 @@ alloc_done: static inline void cache_alloc_debugcheck_before(kmem_cache_t *cachep, int flags) { - if (flags & __GFP_WAIT) - might_sleep(); + might_sleep_if(flags & __GFP_WAIT); #if DEBUG kmem_flagcheck(cachep, flags); #endif _