diff options
-rw-r--r-- | mm/filemap.c | 49 | ||||
-rw-r--r-- | mm/memcontrol.c | 20 | ||||
-rw-r--r-- | mm/truncate.c | 8 |
3 files changed, 40 insertions, 37 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 5020b280a771..000a220e2a41 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -906,8 +906,8 @@ EXPORT_SYMBOL(page_cache_prev_hole); | |||
906 | * Looks up the page cache slot at @mapping & @offset. If there is a | 906 | * Looks up the page cache slot at @mapping & @offset. If there is a |
907 | * page cache page, it is returned with an increased refcount. | 907 | * page cache page, it is returned with an increased refcount. |
908 | * | 908 | * |
909 | * If the slot holds a shadow entry of a previously evicted page, it | 909 | * If the slot holds a shadow entry of a previously evicted page, or a |
910 | * is returned. | 910 | * swap entry from shmem/tmpfs, it is returned. |
911 | * | 911 | * |
912 | * Otherwise, %NULL is returned. | 912 | * Otherwise, %NULL is returned. |
913 | */ | 913 | */ |
@@ -928,9 +928,9 @@ repeat: | |||
928 | if (radix_tree_deref_retry(page)) | 928 | if (radix_tree_deref_retry(page)) |
929 | goto repeat; | 929 | goto repeat; |
930 | /* | 930 | /* |
931 | * Otherwise, shmem/tmpfs must be storing a swap entry | 931 | * A shadow entry of a recently evicted page, |
932 | * here as an exceptional entry: so return it without | 932 | * or a swap entry from shmem/tmpfs. Return |
933 | * attempting to raise page count. | 933 | * it without attempting to raise page count. |
934 | */ | 934 | */ |
935 | goto out; | 935 | goto out; |
936 | } | 936 | } |
@@ -983,8 +983,8 @@ EXPORT_SYMBOL(find_get_page); | |||
983 | * page cache page, it is returned locked and with an increased | 983 | * page cache page, it is returned locked and with an increased |
984 | * refcount. | 984 | * refcount. |
985 | * | 985 | * |
986 | * If the slot holds a shadow entry of a previously evicted page, it | 986 | * If the slot holds a shadow entry of a previously evicted page, or a |
987 | * is returned. | 987 | * swap entry from shmem/tmpfs, it is returned. |
988 | * | 988 | * |
989 | * Otherwise, %NULL is returned. | 989 | * Otherwise, %NULL is returned. |
990 | * | 990 | * |
@@ -1099,8 +1099,8 @@ EXPORT_SYMBOL(find_or_create_page); | |||
1099 | * with ascending indexes. There may be holes in the indices due to | 1099 | * with ascending indexes. There may be holes in the indices due to |
1100 | * not-present pages. | 1100 | * not-present pages. |
1101 | * | 1101 | * |
1102 | * Any shadow entries of evicted pages are included in the returned | 1102 | * Any shadow entries of evicted pages, or swap entries from |
1103 | * array. | 1103 | * shmem/tmpfs, are included in the returned array. |
1104 | * | 1104 | * |
1105 | * find_get_entries() returns the number of pages and shadow entries | 1105 | * find_get_entries() returns the number of pages and shadow entries |
1106 | * which were found. | 1106 | * which were found. |
@@ -1128,9 +1128,9 @@ repeat: | |||
1128 | if (radix_tree_deref_retry(page)) | 1128 | if (radix_tree_deref_retry(page)) |
1129 | goto restart; | 1129 | goto restart; |
1130 | /* | 1130 | /* |
1131 | * Otherwise, we must be storing a swap entry | 1131 | * A shadow entry of a recently evicted page, |
1132 | * here as an exceptional entry: so return it | 1132 | * or a swap entry from shmem/tmpfs. Return |
1133 | * without attempting to raise page count. | 1133 | * it without attempting to raise page count. |
1134 | */ | 1134 | */ |
1135 | goto export; | 1135 | goto export; |
1136 | } | 1136 | } |
@@ -1198,9 +1198,9 @@ repeat: | |||
1198 | goto restart; | 1198 | goto restart; |
1199 | } | 1199 | } |
1200 | /* | 1200 | /* |
1201 | * Otherwise, shmem/tmpfs must be storing a swap entry | 1201 | * A shadow entry of a recently evicted page, |
1202 | * here as an exceptional entry: so skip over it - | 1202 | * or a swap entry from shmem/tmpfs. Skip |
1203 | * we only reach this from invalidate_mapping_pages(). | 1203 | * over it. |
1204 | */ | 1204 | */ |
1205 | continue; | 1205 | continue; |
1206 | } | 1206 | } |
@@ -1265,9 +1265,9 @@ repeat: | |||
1265 | goto restart; | 1265 | goto restart; |
1266 | } | 1266 | } |
1267 | /* | 1267 | /* |
1268 | * Otherwise, shmem/tmpfs must be storing a swap entry | 1268 | * A shadow entry of a recently evicted page, |
1269 | * here as an exceptional entry: so stop looking for | 1269 | * or a swap entry from shmem/tmpfs. Stop |
1270 | * contiguous pages. | 1270 | * looking for contiguous pages. |
1271 | */ | 1271 | */ |
1272 | break; | 1272 | break; |
1273 | } | 1273 | } |
@@ -1341,10 +1341,17 @@ repeat: | |||
1341 | goto restart; | 1341 | goto restart; |
1342 | } | 1342 | } |
1343 | /* | 1343 | /* |
1344 | * This function is never used on a shmem/tmpfs | 1344 | * A shadow entry of a recently evicted page. |
1345 | * mapping, so a swap entry won't be found here. | 1345 | * |
1346 | * Those entries should never be tagged, but | ||
1347 | * this tree walk is lockless and the tags are | ||
1348 | * looked up in bulk, one radix tree node at a | ||
1349 | * time, so there is a sizable window for page | ||
1350 | * reclaim to evict a page we saw tagged. | ||
1351 | * | ||
1352 | * Skip over it. | ||
1346 | */ | 1353 | */ |
1347 | BUG(); | 1354 | continue; |
1348 | } | 1355 | } |
1349 | 1356 | ||
1350 | if (!page_cache_get_speculative(page)) | 1357 | if (!page_cache_get_speculative(page)) |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 29501f040568..c47dffdcb246 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -6686,16 +6686,20 @@ static struct page *mc_handle_file_pte(struct vm_area_struct *vma, | |||
6686 | pgoff = pte_to_pgoff(ptent); | 6686 | pgoff = pte_to_pgoff(ptent); |
6687 | 6687 | ||
6688 | /* page is moved even if it's not RSS of this task(page-faulted). */ | 6688 | /* page is moved even if it's not RSS of this task(page-faulted). */ |
6689 | page = find_get_page(mapping, pgoff); | ||
6690 | |||
6691 | #ifdef CONFIG_SWAP | 6689 | #ifdef CONFIG_SWAP |
6692 | /* shmem/tmpfs may report page out on swap: account for that too. */ | 6690 | /* shmem/tmpfs may report page out on swap: account for that too. */ |
6693 | if (radix_tree_exceptional_entry(page)) { | 6691 | if (shmem_mapping(mapping)) { |
6694 | swp_entry_t swap = radix_to_swp_entry(page); | 6692 | page = find_get_entry(mapping, pgoff); |
6695 | if (do_swap_account) | 6693 | if (radix_tree_exceptional_entry(page)) { |
6696 | *entry = swap; | 6694 | swp_entry_t swp = radix_to_swp_entry(page); |
6697 | page = find_get_page(swap_address_space(swap), swap.val); | 6695 | if (do_swap_account) |
6698 | } | 6696 | *entry = swp; |
6697 | page = find_get_page(swap_address_space(swp), swp.val); | ||
6698 | } | ||
6699 | } else | ||
6700 | page = find_get_page(mapping, pgoff); | ||
6701 | #else | ||
6702 | page = find_get_page(mapping, pgoff); | ||
6699 | #endif | 6703 | #endif |
6700 | return page; | 6704 | return page; |
6701 | } | 6705 | } |
diff --git a/mm/truncate.c b/mm/truncate.c index e5cc39ab0751..6a78c814bebf 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
@@ -484,14 +484,6 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping, | |||
484 | unsigned long count = 0; | 484 | unsigned long count = 0; |
485 | int i; | 485 | int i; |
486 | 486 | ||
487 | /* | ||
488 | * Note: this function may get called on a shmem/tmpfs mapping: | ||
489 | * pagevec_lookup() might then return 0 prematurely (because it | ||
490 | * got a gangful of swap entries); but it's hardly worth worrying | ||
491 | * about - it can rarely have anything to free from such a mapping | ||
492 | * (most pages are dirty), and already skips over any difficulties. | ||
493 | */ | ||
494 | |||
495 | pagevec_init(&pvec, 0); | 487 | pagevec_init(&pvec, 0); |
496 | while (index <= end && pagevec_lookup_entries(&pvec, mapping, index, | 488 | while (index <= end && pagevec_lookup_entries(&pvec, mapping, index, |
497 | min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1, | 489 | min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1, |