diff options
Diffstat (limited to 'mm')
| -rw-r--r-- | mm/filemap.c | 30 | ||||
| -rw-r--r-- | mm/filemap_xip.c | 6 | ||||
| -rw-r--r-- | mm/memory.c | 4 | ||||
| -rw-r--r-- | mm/msync.c | 2 | ||||
| -rw-r--r-- | mm/page_alloc.c | 3 | ||||
| -rw-r--r-- | mm/rmap.c | 8 | ||||
| -rw-r--r-- | mm/shmem.c | 6 | ||||
| -rw-r--r-- | mm/slab.c | 1 | ||||
| -rw-r--r-- | mm/swapfile.c | 8 | ||||
| -rw-r--r-- | mm/truncate.c | 2 |
10 files changed, 37 insertions, 33 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 478f4c74cc31..5fca2737c971 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
| @@ -61,7 +61,7 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
| 61 | * ->swap_lock (exclusive_swap_page, others) | 61 | * ->swap_lock (exclusive_swap_page, others) |
| 62 | * ->mapping->tree_lock | 62 | * ->mapping->tree_lock |
| 63 | * | 63 | * |
| 64 | * ->i_sem | 64 | * ->i_mutex |
| 65 | * ->i_mmap_lock (truncate->unmap_mapping_range) | 65 | * ->i_mmap_lock (truncate->unmap_mapping_range) |
| 66 | * | 66 | * |
| 67 | * ->mmap_sem | 67 | * ->mmap_sem |
| @@ -73,9 +73,9 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
| 73 | * ->lock_page (access_process_vm) | 73 | * ->lock_page (access_process_vm) |
| 74 | * | 74 | * |
| 75 | * ->mmap_sem | 75 | * ->mmap_sem |
| 76 | * ->i_sem (msync) | 76 | * ->i_mutex (msync) |
| 77 | * | 77 | * |
| 78 | * ->i_sem | 78 | * ->i_mutex |
| 79 | * ->i_alloc_sem (various) | 79 | * ->i_alloc_sem (various) |
| 80 | * | 80 | * |
| 81 | * ->inode_lock | 81 | * ->inode_lock |
| @@ -276,7 +276,7 @@ static int wait_on_page_writeback_range(struct address_space *mapping, | |||
| 276 | * integrity" operation. It waits upon in-flight writeout before starting and | 276 | * integrity" operation. It waits upon in-flight writeout before starting and |
| 277 | * waiting upon new writeout. If there was an IO error, return it. | 277 | * waiting upon new writeout. If there was an IO error, return it. |
| 278 | * | 278 | * |
| 279 | * We need to re-take i_sem during the generic_osync_inode list walk because | 279 | * We need to re-take i_mutex during the generic_osync_inode list walk because |
| 280 | * it is otherwise livelockable. | 280 | * it is otherwise livelockable. |
| 281 | */ | 281 | */ |
| 282 | int sync_page_range(struct inode *inode, struct address_space *mapping, | 282 | int sync_page_range(struct inode *inode, struct address_space *mapping, |
| @@ -290,9 +290,9 @@ int sync_page_range(struct inode *inode, struct address_space *mapping, | |||
| 290 | return 0; | 290 | return 0; |
| 291 | ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1); | 291 | ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1); |
| 292 | if (ret == 0) { | 292 | if (ret == 0) { |
| 293 | down(&inode->i_sem); | 293 | mutex_lock(&inode->i_mutex); |
| 294 | ret = generic_osync_inode(inode, mapping, OSYNC_METADATA); | 294 | ret = generic_osync_inode(inode, mapping, OSYNC_METADATA); |
| 295 | up(&inode->i_sem); | 295 | mutex_unlock(&inode->i_mutex); |
| 296 | } | 296 | } |
| 297 | if (ret == 0) | 297 | if (ret == 0) |
| 298 | ret = wait_on_page_writeback_range(mapping, start, end); | 298 | ret = wait_on_page_writeback_range(mapping, start, end); |
| @@ -301,7 +301,7 @@ int sync_page_range(struct inode *inode, struct address_space *mapping, | |||
| 301 | EXPORT_SYMBOL(sync_page_range); | 301 | EXPORT_SYMBOL(sync_page_range); |
| 302 | 302 | ||
| 303 | /* | 303 | /* |
| 304 | * Note: Holding i_sem across sync_page_range_nolock is not a good idea | 304 | * Note: Holding i_mutex across sync_page_range_nolock is not a good idea |
| 305 | * as it forces O_SYNC writers to different parts of the same file | 305 | * as it forces O_SYNC writers to different parts of the same file |
| 306 | * to be serialised right until io completion. | 306 | * to be serialised right until io completion. |
| 307 | */ | 307 | */ |
| @@ -1892,7 +1892,7 @@ generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 1892 | /* | 1892 | /* |
| 1893 | * Sync the fs metadata but not the minor inode changes and | 1893 | * Sync the fs metadata but not the minor inode changes and |
| 1894 | * of course not the data as we did direct DMA for the IO. | 1894 | * of course not the data as we did direct DMA for the IO. |
| 1895 | * i_sem is held, which protects generic_osync_inode() from | 1895 | * i_mutex is held, which protects generic_osync_inode() from |
| 1896 | * livelocking. | 1896 | * livelocking. |
| 1897 | */ | 1897 | */ |
| 1898 | if (written >= 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | 1898 | if (written >= 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |
| @@ -2195,10 +2195,10 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const char __user *buf, | |||
| 2195 | 2195 | ||
| 2196 | BUG_ON(iocb->ki_pos != pos); | 2196 | BUG_ON(iocb->ki_pos != pos); |
| 2197 | 2197 | ||
| 2198 | down(&inode->i_sem); | 2198 | mutex_lock(&inode->i_mutex); |
| 2199 | ret = __generic_file_aio_write_nolock(iocb, &local_iov, 1, | 2199 | ret = __generic_file_aio_write_nolock(iocb, &local_iov, 1, |
| 2200 | &iocb->ki_pos); | 2200 | &iocb->ki_pos); |
| 2201 | up(&inode->i_sem); | 2201 | mutex_unlock(&inode->i_mutex); |
| 2202 | 2202 | ||
| 2203 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | 2203 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |
| 2204 | ssize_t err; | 2204 | ssize_t err; |
| @@ -2220,9 +2220,9 @@ ssize_t generic_file_write(struct file *file, const char __user *buf, | |||
| 2220 | struct iovec local_iov = { .iov_base = (void __user *)buf, | 2220 | struct iovec local_iov = { .iov_base = (void __user *)buf, |
| 2221 | .iov_len = count }; | 2221 | .iov_len = count }; |
| 2222 | 2222 | ||
| 2223 | down(&inode->i_sem); | 2223 | mutex_lock(&inode->i_mutex); |
| 2224 | ret = __generic_file_write_nolock(file, &local_iov, 1, ppos); | 2224 | ret = __generic_file_write_nolock(file, &local_iov, 1, ppos); |
| 2225 | up(&inode->i_sem); | 2225 | mutex_unlock(&inode->i_mutex); |
| 2226 | 2226 | ||
| 2227 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | 2227 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |
| 2228 | ssize_t err; | 2228 | ssize_t err; |
| @@ -2256,9 +2256,9 @@ ssize_t generic_file_writev(struct file *file, const struct iovec *iov, | |||
| 2256 | struct inode *inode = mapping->host; | 2256 | struct inode *inode = mapping->host; |
| 2257 | ssize_t ret; | 2257 | ssize_t ret; |
| 2258 | 2258 | ||
| 2259 | down(&inode->i_sem); | 2259 | mutex_lock(&inode->i_mutex); |
| 2260 | ret = __generic_file_write_nolock(file, iov, nr_segs, ppos); | 2260 | ret = __generic_file_write_nolock(file, iov, nr_segs, ppos); |
| 2261 | up(&inode->i_sem); | 2261 | mutex_unlock(&inode->i_mutex); |
| 2262 | 2262 | ||
| 2263 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { | 2263 | if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |
| 2264 | int err; | 2264 | int err; |
| @@ -2272,7 +2272,7 @@ ssize_t generic_file_writev(struct file *file, const struct iovec *iov, | |||
| 2272 | EXPORT_SYMBOL(generic_file_writev); | 2272 | EXPORT_SYMBOL(generic_file_writev); |
| 2273 | 2273 | ||
| 2274 | /* | 2274 | /* |
| 2275 | * Called under i_sem for writes to S_ISREG files. Returns -EIO if something | 2275 | * Called under i_mutex for writes to S_ISREG files. Returns -EIO if something |
| 2276 | * went wrong during pagecache shootdown. | 2276 | * went wrong during pagecache shootdown. |
| 2277 | */ | 2277 | */ |
| 2278 | static ssize_t | 2278 | static ssize_t |
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c index 9cf687e4a29a..e2b34e95913e 100644 --- a/mm/filemap_xip.c +++ b/mm/filemap_xip.c | |||
| @@ -338,7 +338,7 @@ __xip_file_write(struct file *filp, const char __user *buf, | |||
| 338 | *ppos = pos; | 338 | *ppos = pos; |
| 339 | /* | 339 | /* |
| 340 | * No need to use i_size_read() here, the i_size | 340 | * No need to use i_size_read() here, the i_size |
| 341 | * cannot change under us because we hold i_sem. | 341 | * cannot change under us because we hold i_mutex. |
| 342 | */ | 342 | */ |
| 343 | if (pos > inode->i_size) { | 343 | if (pos > inode->i_size) { |
| 344 | i_size_write(inode, pos); | 344 | i_size_write(inode, pos); |
| @@ -358,7 +358,7 @@ xip_file_write(struct file *filp, const char __user *buf, size_t len, | |||
| 358 | loff_t pos; | 358 | loff_t pos; |
| 359 | ssize_t ret; | 359 | ssize_t ret; |
| 360 | 360 | ||
| 361 | down(&inode->i_sem); | 361 | mutex_lock(&inode->i_mutex); |
| 362 | 362 | ||
| 363 | if (!access_ok(VERIFY_READ, buf, len)) { | 363 | if (!access_ok(VERIFY_READ, buf, len)) { |
| 364 | ret=-EFAULT; | 364 | ret=-EFAULT; |
| @@ -390,7 +390,7 @@ xip_file_write(struct file *filp, const char __user *buf, size_t len, | |||
| 390 | out_backing: | 390 | out_backing: |
| 391 | current->backing_dev_info = NULL; | 391 | current->backing_dev_info = NULL; |
| 392 | out_up: | 392 | out_up: |
| 393 | up(&inode->i_sem); | 393 | mutex_unlock(&inode->i_mutex); |
| 394 | return ret; | 394 | return ret; |
| 395 | } | 395 | } |
| 396 | EXPORT_SYMBOL_GPL(xip_file_write); | 396 | EXPORT_SYMBOL_GPL(xip_file_write); |
diff --git a/mm/memory.c b/mm/memory.c index 3944fec38012..7a11ddd5060f 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -1784,13 +1784,13 @@ int vmtruncate_range(struct inode *inode, loff_t offset, loff_t end) | |||
| 1784 | if (!inode->i_op || !inode->i_op->truncate_range) | 1784 | if (!inode->i_op || !inode->i_op->truncate_range) |
| 1785 | return -ENOSYS; | 1785 | return -ENOSYS; |
| 1786 | 1786 | ||
| 1787 | down(&inode->i_sem); | 1787 | mutex_lock(&inode->i_mutex); |
| 1788 | down_write(&inode->i_alloc_sem); | 1788 | down_write(&inode->i_alloc_sem); |
| 1789 | unmap_mapping_range(mapping, offset, (end - offset), 1); | 1789 | unmap_mapping_range(mapping, offset, (end - offset), 1); |
| 1790 | truncate_inode_pages_range(mapping, offset, end); | 1790 | truncate_inode_pages_range(mapping, offset, end); |
| 1791 | inode->i_op->truncate_range(inode, offset, end); | 1791 | inode->i_op->truncate_range(inode, offset, end); |
| 1792 | up_write(&inode->i_alloc_sem); | 1792 | up_write(&inode->i_alloc_sem); |
| 1793 | up(&inode->i_sem); | 1793 | mutex_unlock(&inode->i_mutex); |
| 1794 | 1794 | ||
| 1795 | return 0; | 1795 | return 0; |
| 1796 | } | 1796 | } |
diff --git a/mm/msync.c b/mm/msync.c index 1b5b6f662dcf..3563a56e1a51 100644 --- a/mm/msync.c +++ b/mm/msync.c | |||
| @@ -137,7 +137,7 @@ static int msync_interval(struct vm_area_struct *vma, | |||
| 137 | ret = filemap_fdatawrite(mapping); | 137 | ret = filemap_fdatawrite(mapping); |
| 138 | if (file->f_op && file->f_op->fsync) { | 138 | if (file->f_op && file->f_op->fsync) { |
| 139 | /* | 139 | /* |
| 140 | * We don't take i_sem here because mmap_sem | 140 | * We don't take i_mutex here because mmap_sem |
| 141 | * is already held. | 141 | * is already held. |
| 142 | */ | 142 | */ |
| 143 | err = file->f_op->fsync(file,file->f_dentry,1); | 143 | err = file->f_op->fsync(file,file->f_dentry,1); |
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) |
| @@ -20,13 +20,13 @@ | |||
| 20 | /* | 20 | /* |
| 21 | * Lock ordering in mm: | 21 | * Lock ordering in mm: |
| 22 | * | 22 | * |
| 23 | * inode->i_sem (while writing or truncating, not reading or faulting) | 23 | * inode->i_mutex (while writing or truncating, not reading or faulting) |
| 24 | * inode->i_alloc_sem | 24 | * inode->i_alloc_sem |
| 25 | * | 25 | * |
| 26 | * When a page fault occurs in writing from user to file, down_read | 26 | * When a page fault occurs in writing from user to file, down_read |
| 27 | * of mmap_sem nests within i_sem; in sys_msync, i_sem nests within | 27 | * of mmap_sem nests within i_mutex; in sys_msync, i_mutex nests within |
| 28 | * down_read of mmap_sem; i_sem and down_write of mmap_sem are never | 28 | * down_read of mmap_sem; i_mutex and down_write of mmap_sem are never |
| 29 | * taken together; in truncation, i_sem is taken outermost. | 29 | * taken together; in truncation, i_mutex is taken outermost. |
| 30 | * | 30 | * |
| 31 | * mm->mmap_sem | 31 | * mm->mmap_sem |
| 32 | * page->flags PG_locked (lock_page) | 32 | * page->flags PG_locked (lock_page) |
diff --git a/mm/shmem.c b/mm/shmem.c index a1f2f02af724..343b3c0937e5 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
| @@ -1370,7 +1370,7 @@ shmem_file_write(struct file *file, const char __user *buf, size_t count, loff_t | |||
| 1370 | if (!access_ok(VERIFY_READ, buf, count)) | 1370 | if (!access_ok(VERIFY_READ, buf, count)) |
| 1371 | return -EFAULT; | 1371 | return -EFAULT; |
| 1372 | 1372 | ||
| 1373 | down(&inode->i_sem); | 1373 | mutex_lock(&inode->i_mutex); |
| 1374 | 1374 | ||
| 1375 | pos = *ppos; | 1375 | pos = *ppos; |
| 1376 | written = 0; | 1376 | written = 0; |
| @@ -1455,7 +1455,7 @@ shmem_file_write(struct file *file, const char __user *buf, size_t count, loff_t | |||
| 1455 | if (written) | 1455 | if (written) |
| 1456 | err = written; | 1456 | err = written; |
| 1457 | out: | 1457 | out: |
| 1458 | up(&inode->i_sem); | 1458 | mutex_unlock(&inode->i_mutex); |
| 1459 | return err; | 1459 | return err; |
| 1460 | } | 1460 | } |
| 1461 | 1461 | ||
| @@ -1491,7 +1491,7 @@ static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_ | |||
| 1491 | 1491 | ||
| 1492 | /* | 1492 | /* |
| 1493 | * We must evaluate after, since reads (unlike writes) | 1493 | * We must evaluate after, since reads (unlike writes) |
| 1494 | * are called without i_sem protection against truncate | 1494 | * are called without i_mutex protection against truncate |
| 1495 | */ | 1495 | */ |
| 1496 | nr = PAGE_CACHE_SIZE; | 1496 | nr = PAGE_CACHE_SIZE; |
| 1497 | i_size = i_size_read(inode); | 1497 | i_size = i_size_read(inode); |
| @@ -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 | } |
diff --git a/mm/swapfile.c b/mm/swapfile.c index 80f948a2028b..6544565a7c0f 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
| @@ -1187,9 +1187,9 @@ asmlinkage long sys_swapoff(const char __user * specialfile) | |||
| 1187 | set_blocksize(bdev, p->old_block_size); | 1187 | set_blocksize(bdev, p->old_block_size); |
| 1188 | bd_release(bdev); | 1188 | bd_release(bdev); |
| 1189 | } else { | 1189 | } else { |
| 1190 | down(&inode->i_sem); | 1190 | mutex_lock(&inode->i_mutex); |
| 1191 | inode->i_flags &= ~S_SWAPFILE; | 1191 | inode->i_flags &= ~S_SWAPFILE; |
| 1192 | up(&inode->i_sem); | 1192 | mutex_unlock(&inode->i_mutex); |
| 1193 | } | 1193 | } |
| 1194 | filp_close(swap_file, NULL); | 1194 | filp_close(swap_file, NULL); |
| 1195 | err = 0; | 1195 | err = 0; |
| @@ -1406,7 +1406,7 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) | |||
| 1406 | p->bdev = bdev; | 1406 | p->bdev = bdev; |
| 1407 | } else if (S_ISREG(inode->i_mode)) { | 1407 | } else if (S_ISREG(inode->i_mode)) { |
| 1408 | p->bdev = inode->i_sb->s_bdev; | 1408 | p->bdev = inode->i_sb->s_bdev; |
| 1409 | down(&inode->i_sem); | 1409 | mutex_lock(&inode->i_mutex); |
| 1410 | did_down = 1; | 1410 | did_down = 1; |
| 1411 | if (IS_SWAPFILE(inode)) { | 1411 | if (IS_SWAPFILE(inode)) { |
| 1412 | error = -EBUSY; | 1412 | error = -EBUSY; |
| @@ -1596,7 +1596,7 @@ out: | |||
| 1596 | if (did_down) { | 1596 | if (did_down) { |
| 1597 | if (!error) | 1597 | if (!error) |
| 1598 | inode->i_flags |= S_SWAPFILE; | 1598 | inode->i_flags |= S_SWAPFILE; |
| 1599 | up(&inode->i_sem); | 1599 | mutex_unlock(&inode->i_mutex); |
| 1600 | } | 1600 | } |
| 1601 | return error; | 1601 | return error; |
| 1602 | } | 1602 | } |
diff --git a/mm/truncate.c b/mm/truncate.c index b1a463d0fe71..6cb3fff25f67 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
| @@ -196,7 +196,7 @@ EXPORT_SYMBOL(truncate_inode_pages_range); | |||
| 196 | * @mapping: mapping to truncate | 196 | * @mapping: mapping to truncate |
| 197 | * @lstart: offset from which to truncate | 197 | * @lstart: offset from which to truncate |
| 198 | * | 198 | * |
| 199 | * Called under (and serialised by) inode->i_sem. | 199 | * Called under (and serialised by) inode->i_mutex. |
| 200 | */ | 200 | */ |
| 201 | void truncate_inode_pages(struct address_space *mapping, loff_t lstart) | 201 | void truncate_inode_pages(struct address_space *mapping, loff_t lstart) |
| 202 | { | 202 | { |
