From: Ingo Molnar , Arjan van de Ven Add a whole bunch more might_sleep() checks. We also enable might_sleep() checking in copy_*_user(). This was non-trivial because of the "copy_*_user() in atomic regions" trick would generate false positives. Fix that up by adding a new __copy_*_user_inatomic(), which avoids the might_sleep() check. Only i386 is supported in this patch. Signed-off-by: Andrew Morton --- 25-akpm/arch/i386/lib/usercopy.c | 2 ++ 25-akpm/drivers/block/ll_rw_blk.c | 1 + 25-akpm/fs/buffer.c | 3 +++ 25-akpm/fs/ext3/inode.c | 3 +++ 25-akpm/fs/fs-writeback.c | 1 + 25-akpm/fs/inode.c | 1 + 25-akpm/fs/jbd/revoke.c | 1 + 25-akpm/fs/proc/base.c | 1 + 25-akpm/include/asm-alpha/uaccess.h | 4 ++++ 25-akpm/include/asm-arm/uaccess.h | 3 +++ 25-akpm/include/asm-arm26/uaccess.h | 3 +++ 25-akpm/include/asm-cris/uaccess.h | 2 ++ 25-akpm/include/asm-h8300/uaccess.h | 2 ++ 25-akpm/include/asm-i386/checksum.h | 2 ++ 25-akpm/include/asm-i386/uaccess.h | 17 +++++++++++++++-- 25-akpm/include/asm-ia64/uaccess.h | 3 ++- 25-akpm/include/asm-m68k/uaccess.h | 3 +++ 25-akpm/include/asm-m68knommu/uaccess.h | 2 ++ 25-akpm/include/asm-mips/uaccess.h | 3 +++ 25-akpm/include/asm-parisc/uaccess.h | 2 ++ 25-akpm/include/asm-ppc/uaccess.h | 2 ++ 25-akpm/include/asm-ppc64/uaccess.h | 3 +++ 25-akpm/include/asm-s390/uaccess.h | 3 +++ 25-akpm/include/asm-sh/uaccess.h | 4 ++++ 25-akpm/include/asm-sh64/uaccess.h | 3 +++ 25-akpm/include/asm-sparc/uaccess.h | 3 +++ 25-akpm/include/asm-sparc64/uaccess.h | 2 ++ 25-akpm/include/asm-um/uaccess.h | 3 +++ 25-akpm/include/asm-v850/uaccess.h | 3 +++ 25-akpm/include/asm-x86_64/uaccess.h | 3 +++ 25-akpm/include/linux/buffer_head.h | 1 + 25-akpm/include/linux/pagemap.h | 1 + 25-akpm/include/linux/writeback.h | 1 + 25-akpm/mm/filemap.c | 4 ++-- 25-akpm/mm/mempool.c | 1 + 35 files changed, 91 insertions(+), 5 deletions(-) diff -puN arch/i386/lib/usercopy.c~add-a-few-might_sleep-checks arch/i386/lib/usercopy.c --- 25/arch/i386/lib/usercopy.c~add-a-few-might_sleep-checks 2004-07-13 13:18:19.342372656 -0700 +++ 25-akpm/arch/i386/lib/usercopy.c 2004-07-13 13:18:19.409362472 -0700 @@ -31,6 +31,7 @@ static inline int __movsl_is_ok(unsigned #define __do_strncpy_from_user(dst,src,count,res) \ do { \ int __d0, __d1, __d2; \ + might_sleep(); \ __asm__ __volatile__( \ " testl %1,%1\n" \ " jz 2f\n" \ @@ -119,6 +120,7 @@ strncpy_from_user(char *dst, const char #define __do_clear_user(addr,size) \ do { \ int __d0; \ + might_sleep(); \ __asm__ __volatile__( \ "0: rep; stosl\n" \ " movl %2,%0\n" \ diff -puN drivers/block/ll_rw_blk.c~add-a-few-might_sleep-checks drivers/block/ll_rw_blk.c --- 25/drivers/block/ll_rw_blk.c~add-a-few-might_sleep-checks 2004-07-13 13:18:19.344372352 -0700 +++ 25-akpm/drivers/block/ll_rw_blk.c 2004-07-13 13:18:19.412362016 -0700 @@ -2499,6 +2499,7 @@ void generic_make_request(struct bio *bi sector_t maxsector; int ret, nr_sectors = bio_sectors(bio); + might_sleep(); /* Test device or partition size, when known. */ maxsector = bio->bi_bdev->bd_inode->i_size >> 9; if (maxsector) { diff -puN fs/buffer.c~add-a-few-might_sleep-checks fs/buffer.c --- 25/fs/buffer.c~add-a-few-might_sleep-checks 2004-07-13 13:18:19.346372048 -0700 +++ 25-akpm/fs/buffer.c 2004-07-13 13:18:19.414361712 -0700 @@ -1551,6 +1551,7 @@ __getblk(struct block_device *bdev, sect { struct buffer_head *bh = __find_get_block(bdev, block, size); + might_sleep(); if (bh == NULL) bh = __getblk_slow(bdev, block, size); return bh; @@ -1776,6 +1777,8 @@ void unmap_underlying_metadata(struct bl { struct buffer_head *old_bh; + might_sleep(); + old_bh = __find_get_block_slow(bdev, block, 0); if (old_bh) { clear_buffer_dirty(old_bh); diff -puN fs/ext3/inode.c~add-a-few-might_sleep-checks fs/ext3/inode.c --- 25/fs/ext3/inode.c~add-a-few-might_sleep-checks 2004-07-13 13:18:19.348371744 -0700 +++ 25-akpm/fs/ext3/inode.c 2004-07-13 13:18:19.416361408 -0700 @@ -66,6 +66,8 @@ int ext3_forget(handle_t *handle, int is { int err; + might_sleep(); + BUFFER_TRACE(bh, "enter"); jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, " @@ -2870,6 +2872,7 @@ int ext3_mark_inode_dirty(handle_t *hand struct ext3_iloc iloc; int err; + might_sleep(); err = ext3_reserve_inode_write(handle, inode, &iloc); if (!err) err = ext3_mark_iloc_dirty(handle, inode, &iloc); diff -puN fs/fs-writeback.c~add-a-few-might_sleep-checks fs/fs-writeback.c --- 25/fs/fs-writeback.c~add-a-few-might_sleep-checks 2004-07-13 13:18:19.350371440 -0700 +++ 25-akpm/fs/fs-writeback.c 2004-07-13 13:18:19.417361256 -0700 @@ -397,6 +397,7 @@ writeback_inodes(struct writeback_contro { struct super_block *sb; + might_sleep(); spin_lock(&inode_lock); spin_lock(&sb_lock); restart: diff -puN fs/inode.c~add-a-few-might_sleep-checks fs/inode.c --- 25/fs/inode.c~add-a-few-might_sleep-checks 2004-07-13 13:18:19.351371288 -0700 +++ 25-akpm/fs/inode.c 2004-07-13 13:18:19.418361104 -0700 @@ -243,6 +243,7 @@ void __iget(struct inode * inode) */ void clear_inode(struct inode *inode) { + might_sleep(); invalidate_inode_buffers(inode); if (inode->i_data.nrpages) diff -puN fs/jbd/revoke.c~add-a-few-might_sleep-checks fs/jbd/revoke.c --- 25/fs/jbd/revoke.c~add-a-few-might_sleep-checks 2004-07-13 13:18:19.353370984 -0700 +++ 25-akpm/fs/jbd/revoke.c 2004-07-13 13:18:19.419360952 -0700 @@ -332,6 +332,7 @@ int journal_revoke(handle_t *handle, uns struct block_device *bdev; int err; + might_sleep(); if (bh_in) BUFFER_TRACE(bh_in, "enter"); diff -puN fs/proc/base.c~add-a-few-might_sleep-checks fs/proc/base.c --- 25/fs/proc/base.c~add-a-few-might_sleep-checks 2004-07-13 13:18:19.354370832 -0700 +++ 25-akpm/fs/proc/base.c 2004-07-13 13:18:19.420360800 -0700 @@ -1526,6 +1526,7 @@ struct dentry *proc_pid_unhash(struct ta void proc_pid_flush(struct dentry *proc_dentry) { + might_sleep(); if(proc_dentry != NULL) { shrink_dcache_parent(proc_dentry); dput(proc_dentry); diff -puN include/asm-alpha/uaccess.h~add-a-few-might_sleep-checks include/asm-alpha/uaccess.h --- 25/include/asm-alpha/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.356370528 -0700 +++ 25-akpm/include/asm-alpha/uaccess.h 2004-07-13 13:18:19.421360648 -0700 @@ -395,6 +395,10 @@ __copy_tofrom_user(void *to, const void __copy_tofrom_user_nocheck((to),(__force void *)(from),(n)); \ }) +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + + extern inline long copy_to_user(void __user *to, const void *from, long n) { diff -puN include/asm-arm26/uaccess.h~add-a-few-might_sleep-checks include/asm-arm26/uaccess.h --- 25/include/asm-arm26/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.357370376 -0700 +++ 25-akpm/include/asm-arm26/uaccess.h 2004-07-13 13:18:19.421360648 -0700 @@ -217,6 +217,9 @@ static __inline__ unsigned long __copy_t return n; } +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + static __inline__ unsigned long clear_user (void *to, unsigned long n) { if (access_ok(VERIFY_WRITE, to, n)) diff -puN include/asm-arm/uaccess.h~add-a-few-might_sleep-checks include/asm-arm/uaccess.h --- 25/include/asm-arm/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.359370072 -0700 +++ 25-akpm/include/asm-arm/uaccess.h 2004-07-13 13:18:19.422360496 -0700 @@ -391,6 +391,9 @@ static inline unsigned long __copy_to_us return __arch_copy_to_user(to, from, n); } +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + static inline unsigned long clear_user (void __user *to, unsigned long n) { if (access_ok(VERIFY_WRITE, to, n)) diff -puN include/asm-cris/uaccess.h~add-a-few-might_sleep-checks include/asm-cris/uaccess.h --- 25/include/asm-cris/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.360369920 -0700 +++ 25-akpm/include/asm-cris/uaccess.h 2004-07-13 13:18:19.423360344 -0700 @@ -434,6 +434,8 @@ __generic_clear_user_nocheck(void *to, u #define __copy_to_user(to,from,n) __generic_copy_to_user_nocheck((to),(from),(n)) #define __copy_from_user(to,from,n) __generic_copy_from_user_nocheck((to),(from),(n)) +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user #define __clear_user(to,n) __generic_clear_user_nocheck((to),(n)) #define strlen_user(str) strnlen_user((str), 0x7ffffffe) diff -puN include/asm-h8300/uaccess.h~add-a-few-might_sleep-checks include/asm-h8300/uaccess.h --- 25/include/asm-h8300/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.362369616 -0700 +++ 25-akpm/include/asm-h8300/uaccess.h 2004-07-13 13:18:19.423360344 -0700 @@ -123,6 +123,8 @@ extern int __get_user_bad(void); #define __copy_from_user(to, from, n) copy_from_user(to, from, n) #define __copy_to_user(to, from, n) copy_to_user(to, from, n) +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user #define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; }) diff -puN include/asm-i386/checksum.h~add-a-few-might_sleep-checks include/asm-i386/checksum.h --- 25/include/asm-i386/checksum.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.363369464 -0700 +++ 25-akpm/include/asm-i386/checksum.h 2004-07-13 13:18:19.423360344 -0700 @@ -46,6 +46,7 @@ static __inline__ unsigned int csum_partial_copy_from_user ( const char *src, char *dst, int len, int sum, int *err_ptr) { + might_sleep(); return csum_partial_copy_generic ( src, dst, len, sum, err_ptr, NULL); } @@ -177,6 +178,7 @@ static __inline__ unsigned int csum_and_ int len, int sum, int *err_ptr) { + might_sleep(); if (access_ok(VERIFY_WRITE, dst, len)) return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr); diff -puN include/asm-i386/uaccess.h~add-a-few-might_sleep-checks include/asm-i386/uaccess.h --- 25/include/asm-i386/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.364369312 -0700 +++ 25-akpm/include/asm-i386/uaccess.h 2004-07-13 13:18:19.424360192 -0700 @@ -400,7 +400,7 @@ unsigned long __copy_from_user_ll(void * * On success, this will be zero. */ static inline unsigned long -__copy_to_user(void __user *to, const void *from, unsigned long n) +__copy_to_user_inatomic(void __user *to, const void *from, unsigned long n) { if (__builtin_constant_p(n)) { unsigned long ret; @@ -420,6 +420,13 @@ __copy_to_user(void __user *to, const vo return __copy_to_user_ll(to, from, n); } +static inline unsigned long +__copy_to_user(void __user *to, const void *from, unsigned long n) +{ + might_sleep(); + return __copy_to_user_inatomic(to, from, n); +} + /** * __copy_from_user: - Copy a block of data from user space, with less checking. * @to: Destination address, in kernel space. @@ -438,7 +445,7 @@ __copy_to_user(void __user *to, const vo * data to the requested size using zero bytes. */ static inline unsigned long -__copy_from_user(void *to, const void __user *from, unsigned long n) +__copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) { if (__builtin_constant_p(n)) { unsigned long ret; @@ -458,6 +465,12 @@ __copy_from_user(void *to, const void __ return __copy_from_user_ll(to, from, n); } +static inline unsigned long +__copy_from_user(void *to, const void __user *from, unsigned long n) +{ + might_sleep(); + return __copy_from_user_inatomic(to, from, n); +} unsigned long copy_to_user(void __user *to, const void *from, unsigned long n); unsigned long copy_from_user(void *to, const void __user *from, unsigned long n); diff -puN include/asm-ia64/uaccess.h~add-a-few-might_sleep-checks include/asm-ia64/uaccess.h --- 25/include/asm-ia64/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.366369008 -0700 +++ 25-akpm/include/asm-ia64/uaccess.h 2004-07-13 13:18:19.425360040 -0700 @@ -202,7 +202,8 @@ extern unsigned long __copy_user (void * #define __copy_to_user(to, from, n) __copy_user((to), (from), (n)) #define __copy_from_user(to, from, n) __copy_user((to), (from), (n)) - +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user #define copy_to_user(to, from, n) __copy_tofrom_user((to), (from), (n), 1) #define copy_from_user(to, from, n) __copy_tofrom_user((to), (from), (n), 0) diff -puN include/asm-m68knommu/uaccess.h~add-a-few-might_sleep-checks include/asm-m68knommu/uaccess.h --- 25/include/asm-m68knommu/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.367368856 -0700 +++ 25-akpm/include/asm-m68knommu/uaccess.h 2004-07-13 13:18:19.425360040 -0700 @@ -134,6 +134,8 @@ extern int __get_user_bad(void); #define __copy_from_user(to, from, n) copy_from_user(to, from, n) #define __copy_to_user(to, from, n) copy_to_user(to, from, n) +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user #define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; }) diff -puN include/asm-m68k/uaccess.h~add-a-few-might_sleep-checks include/asm-m68k/uaccess.h --- 25/include/asm-m68k/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.369368552 -0700 +++ 25-akpm/include/asm-m68k/uaccess.h 2004-07-13 13:18:19.426359888 -0700 @@ -521,6 +521,9 @@ __constant_copy_from_user(void *to, cons : "0"(to), "1"(from), "2"(n/4) \ : "d0", "memory") +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + static inline unsigned long __constant_copy_to_user(void *to, const void *from, unsigned long n) { diff -puN include/asm-mips/uaccess.h~add-a-few-might_sleep-checks include/asm-mips/uaccess.h --- 25/include/asm-mips/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.370368400 -0700 +++ 25-akpm/include/asm-mips/uaccess.h 2004-07-13 13:18:19.427359736 -0700 @@ -463,6 +463,9 @@ extern size_t __copy_user(void *__to, co __cu_len; \ }) +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + /* * copy_to_user: - Copy a block of data into user space. * @to: Destination address, in user space. diff -puN include/asm-parisc/uaccess.h~add-a-few-might_sleep-checks include/asm-parisc/uaccess.h --- 25/include/asm-parisc/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.372368096 -0700 +++ 25-akpm/include/asm-parisc/uaccess.h 2004-07-13 13:18:19.427359736 -0700 @@ -279,5 +279,7 @@ extern long lstrnlen_user(const char __u #define __copy_to_user lcopy_to_user #define copy_in_user lcopy_in_user #define __copy_in_user lcopy_in_user +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user #endif /* __PARISC_UACCESS_H */ diff -puN include/asm-ppc64/uaccess.h~add-a-few-might_sleep-checks include/asm-ppc64/uaccess.h --- 25/include/asm-ppc64/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.373367944 -0700 +++ 25-akpm/include/asm-ppc64/uaccess.h 2004-07-13 13:18:19.428359584 -0700 @@ -281,6 +281,9 @@ extern unsigned long copy_in_user(void _ extern unsigned long __clear_user(void __user *addr, unsigned long size); +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + static inline unsigned long clear_user(void __user *addr, unsigned long size) { diff -puN include/asm-ppc/uaccess.h~add-a-few-might_sleep-checks include/asm-ppc/uaccess.h --- 25/include/asm-ppc/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.375367640 -0700 +++ 25-akpm/include/asm-ppc/uaccess.h 2004-07-13 13:18:19.428359584 -0700 @@ -327,6 +327,8 @@ copy_to_user(void __user *to, const void __copy_tofrom_user((void __user *)(to), (from), (size)) #define __copy_to_user(to, from, size) \ __copy_tofrom_user((to), (void __user *)(from), (size)) +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user extern unsigned long __clear_user(void __user *addr, unsigned long size); diff -puN include/asm-s390/uaccess.h~add-a-few-might_sleep-checks include/asm-s390/uaccess.h --- 25/include/asm-s390/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.376367488 -0700 +++ 25-akpm/include/asm-s390/uaccess.h 2004-07-13 13:18:19.429359432 -0700 @@ -272,6 +272,9 @@ __copy_to_user(void __user *to, const vo return __copy_to_user_asm(from, n, to); } +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + /** * copy_to_user: - Copy a block of data into user space. * @to: Destination address, in user space. diff -puN include/asm-sh64/uaccess.h~add-a-few-might_sleep-checks include/asm-sh64/uaccess.h --- 25/include/asm-sh64/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.386365968 -0700 +++ 25-akpm/include/asm-sh64/uaccess.h 2004-07-13 13:18:19.429359432 -0700 @@ -261,6 +261,9 @@ if (__copy_from_user(to,from,n)) \ return retval; \ }) +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + /* XXX: Not sure it works well.. should be such that: 4byte clear and the rest. */ extern __kernel_size_t __clear_user(void *addr, __kernel_size_t size); diff -puN include/asm-sh/uaccess.h~add-a-few-might_sleep-checks include/asm-sh/uaccess.h --- 25/include/asm-sh/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.388365664 -0700 +++ 25-akpm/include/asm-sh/uaccess.h 2004-07-13 13:18:19.430359280 -0700 @@ -446,6 +446,10 @@ __copy_res; }) __copy_user((void *)(to), \ (void *)(from), n) +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + + #define copy_from_user(to,from,n) ({ \ void *__copy_to = (void *) (to); \ void *__copy_from = (void *) (from); \ diff -puN include/asm-sparc64/uaccess.h~add-a-few-might_sleep-checks include/asm-sparc64/uaccess.h --- 25/include/asm-sparc64/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.389365512 -0700 +++ 25-akpm/include/asm-sparc64/uaccess.h 2004-07-13 13:18:19.430359280 -0700 @@ -264,6 +264,8 @@ extern unsigned long __copy_in_user(void #define copy_from_user __copy_from_user #define copy_to_user __copy_to_user #define copy_in_user __copy_in_user +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user extern unsigned long __bzero_noasi(void __user *, unsigned long); diff -puN include/asm-sparc/uaccess.h~add-a-few-might_sleep-checks include/asm-sparc/uaccess.h --- 25/include/asm-sparc/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.391365208 -0700 +++ 25-akpm/include/asm-sparc/uaccess.h 2004-07-13 13:18:19.431359128 -0700 @@ -322,6 +322,9 @@ static inline unsigned long __copy_from_ return __copy_user((void __user *) to, from, n); } +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + static inline unsigned long __clear_user(void __user *addr, unsigned long size) { unsigned long ret; diff -puN include/asm-um/uaccess.h~add-a-few-might_sleep-checks include/asm-um/uaccess.h --- 25/include/asm-um/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.392365056 -0700 +++ 25-akpm/include/asm-um/uaccess.h 2004-07-13 13:18:19.431359128 -0700 @@ -36,6 +36,9 @@ #define __copy_to_user(to, from, n) copy_to_user(to, from, n) +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + #define __get_user(x, ptr) \ ({ \ const __typeof__(ptr) __private_ptr = ptr; \ diff -puN include/asm-v850/uaccess.h~add-a-few-might_sleep-checks include/asm-v850/uaccess.h --- 25/include/asm-v850/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.394364752 -0700 +++ 25-akpm/include/asm-v850/uaccess.h 2004-07-13 13:18:19.432358976 -0700 @@ -112,6 +112,9 @@ extern int bad_user_access_length (void) #define __copy_from_user(to, from, n) (memcpy (to, from, n), 0) #define __copy_to_user(to, from, n) (memcpy(to, from, n), 0) +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + #define copy_from_user(to, from, n) __copy_from_user (to, from, n) #define copy_to_user(to, from, n) __copy_to_user(to, from, n) diff -puN include/asm-x86_64/uaccess.h~add-a-few-might_sleep-checks include/asm-x86_64/uaccess.h --- 25/include/asm-x86_64/uaccess.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.395364600 -0700 +++ 25-akpm/include/asm-x86_64/uaccess.h 2004-07-13 13:18:19.432358976 -0700 @@ -351,4 +351,7 @@ long strlen_user(const char __user *str) unsigned long clear_user(void __user *mem, unsigned long len); unsigned long __clear_user(void __user *mem, unsigned long len); +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + #endif /* __X86_64_UACCESS_H */ diff -puN include/linux/buffer_head.h~add-a-few-might_sleep-checks include/linux/buffer_head.h --- 25/include/linux/buffer_head.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.400363840 -0700 +++ 25-akpm/include/linux/buffer_head.h 2004-07-13 13:18:19.433358824 -0700 @@ -278,6 +278,7 @@ map_bh(struct buffer_head *bh, struct su */ static inline void wait_on_buffer(struct buffer_head *bh) { + might_sleep(); if (buffer_locked(bh) || atomic_read(&bh->b_count) == 0) __wait_on_buffer(bh); } diff -puN include/linux/pagemap.h~add-a-few-might_sleep-checks include/linux/pagemap.h --- 25/include/linux/pagemap.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.401363688 -0700 +++ 25-akpm/include/linux/pagemap.h 2004-07-13 13:18:19.433358824 -0700 @@ -156,6 +156,7 @@ extern void FASTCALL(unlock_page(struct static inline void lock_page(struct page *page) { + might_sleep(); if (TestSetPageLocked(page)) __lock_page(page); } diff -puN include/linux/writeback.h~add-a-few-might_sleep-checks include/linux/writeback.h --- 25/include/linux/writeback.h~add-a-few-might_sleep-checks 2004-07-13 13:18:19.403363384 -0700 +++ 25-akpm/include/linux/writeback.h 2004-07-13 13:18:19.434358672 -0700 @@ -64,6 +64,7 @@ void sync_inodes(int wait); /* writeback.h requires fs.h; it, too, is not included from here. */ static inline void wait_on_inode(struct inode *inode) { + might_sleep(); if (inode->i_state & I_LOCK) __wait_on_inode(inode); } diff -puN mm/filemap.c~add-a-few-might_sleep-checks mm/filemap.c --- 25/mm/filemap.c~add-a-few-might_sleep-checks 2004-07-13 13:18:19.404363232 -0700 +++ 25-akpm/mm/filemap.c 2004-07-13 13:18:19.435358520 -0700 @@ -838,7 +838,7 @@ int file_read_actor(read_descriptor_t *d */ if (!fault_in_pages_writeable(desc->buf, size)) { kaddr = kmap_atomic(page, KM_USER0); - left = __copy_to_user(desc->buf, kaddr + offset, size); + left = __copy_to_user_inatomic(desc->buf, kaddr + offset, size); kunmap_atomic(kaddr, KM_USER0); if (left == 0) goto success; @@ -1640,7 +1640,7 @@ filemap_copy_from_user(struct page *page int left; kaddr = kmap_atomic(page, KM_USER0); - left = __copy_from_user(kaddr + offset, buf, bytes); + left = __copy_from_user_inatomic(kaddr + offset, buf, bytes); kunmap_atomic(kaddr, KM_USER0); if (left != 0) { diff -puN mm/mempool.c~add-a-few-might_sleep-checks mm/mempool.c --- 25/mm/mempool.c~add-a-few-might_sleep-checks 2004-07-13 13:18:19.406362928 -0700 +++ 25-akpm/mm/mempool.c 2004-07-13 13:18:19.436358368 -0700 @@ -194,6 +194,7 @@ void * mempool_alloc(mempool_t *pool, in DEFINE_WAIT(wait); int gfp_nowait = gfp_mask & ~(__GFP_WAIT | __GFP_IO); + might_sleep_if(gfp_mask & __GFP_WAIT); repeat_alloc: element = pool->alloc(gfp_nowait|__GFP_NOWARN, pool->pool_data); if (likely(element != NULL)) _