diff options
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 903bf316912a..ab8553658af3 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/cpuset.h> | 33 | #include <linux/cpuset.h> |
34 | #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */ | 34 | #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */ |
35 | #include <linux/memcontrol.h> | 35 | #include <linux/memcontrol.h> |
36 | #include <linux/mm_inline.h> /* for page_is_file_cache() */ | ||
36 | #include "internal.h" | 37 | #include "internal.h" |
37 | 38 | ||
38 | /* | 39 | /* |
@@ -115,12 +116,12 @@ void __remove_from_page_cache(struct page *page) | |||
115 | { | 116 | { |
116 | struct address_space *mapping = page->mapping; | 117 | struct address_space *mapping = page->mapping; |
117 | 118 | ||
118 | mem_cgroup_uncharge_cache_page(page); | ||
119 | radix_tree_delete(&mapping->page_tree, page->index); | 119 | radix_tree_delete(&mapping->page_tree, page->index); |
120 | page->mapping = NULL; | 120 | page->mapping = NULL; |
121 | mapping->nrpages--; | 121 | mapping->nrpages--; |
122 | __dec_zone_page_state(page, NR_FILE_PAGES); | 122 | __dec_zone_page_state(page, NR_FILE_PAGES); |
123 | BUG_ON(page_mapped(page)); | 123 | BUG_ON(page_mapped(page)); |
124 | mem_cgroup_uncharge_cache_page(page); | ||
124 | 125 | ||
125 | /* | 126 | /* |
126 | * Some filesystems seem to re-dirty the page even after | 127 | * Some filesystems seem to re-dirty the page even after |
@@ -492,9 +493,24 @@ EXPORT_SYMBOL(add_to_page_cache_locked); | |||
492 | int add_to_page_cache_lru(struct page *page, struct address_space *mapping, | 493 | int add_to_page_cache_lru(struct page *page, struct address_space *mapping, |
493 | pgoff_t offset, gfp_t gfp_mask) | 494 | pgoff_t offset, gfp_t gfp_mask) |
494 | { | 495 | { |
495 | int ret = add_to_page_cache(page, mapping, offset, gfp_mask); | 496 | int ret; |
496 | if (ret == 0) | 497 | |
497 | lru_cache_add(page); | 498 | /* |
499 | * Splice_read and readahead add shmem/tmpfs pages into the page cache | ||
500 | * before shmem_readpage has a chance to mark them as SwapBacked: they | ||
501 | * need to go on the active_anon lru below, and mem_cgroup_cache_charge | ||
502 | * (called in add_to_page_cache) needs to know where they're going too. | ||
503 | */ | ||
504 | if (mapping_cap_swap_backed(mapping)) | ||
505 | SetPageSwapBacked(page); | ||
506 | |||
507 | ret = add_to_page_cache(page, mapping, offset, gfp_mask); | ||
508 | if (ret == 0) { | ||
509 | if (page_is_file_cache(page)) | ||
510 | lru_cache_add_file(page); | ||
511 | else | ||
512 | lru_cache_add_active_anon(page); | ||
513 | } | ||
498 | return ret; | 514 | return ret; |
499 | } | 515 | } |
500 | 516 | ||
@@ -557,17 +573,14 @@ EXPORT_SYMBOL(wait_on_page_bit); | |||
557 | * mechananism between PageLocked pages and PageWriteback pages is shared. | 573 | * mechananism between PageLocked pages and PageWriteback pages is shared. |
558 | * But that's OK - sleepers in wait_on_page_writeback() just go back to sleep. | 574 | * But that's OK - sleepers in wait_on_page_writeback() just go back to sleep. |
559 | * | 575 | * |
560 | * The first mb is necessary to safely close the critical section opened by the | 576 | * The mb is necessary to enforce ordering between the clear_bit and the read |
561 | * test_and_set_bit() to lock the page; the second mb is necessary to enforce | 577 | * of the waitqueue (to avoid SMP races with a parallel wait_on_page_locked()). |
562 | * ordering between the clear_bit and the read of the waitqueue (to avoid SMP | ||
563 | * races with a parallel wait_on_page_locked()). | ||
564 | */ | 578 | */ |
565 | void unlock_page(struct page *page) | 579 | void unlock_page(struct page *page) |
566 | { | 580 | { |
567 | smp_mb__before_clear_bit(); | 581 | VM_BUG_ON(!PageLocked(page)); |
568 | if (!test_and_clear_bit(PG_locked, &page->flags)) | 582 | clear_bit_unlock(PG_locked, &page->flags); |
569 | BUG(); | 583 | smp_mb__after_clear_bit(); |
570 | smp_mb__after_clear_bit(); | ||
571 | wake_up_page(page, PG_locked); | 584 | wake_up_page(page, PG_locked); |
572 | } | 585 | } |
573 | EXPORT_SYMBOL(unlock_page); | 586 | EXPORT_SYMBOL(unlock_page); |