Commit 8079b1c8 authored by Hugh Dickins's avatar Hugh Dickins Committed by Linus Torvalds

mm: clarify the radix_tree exceptional cases

Make the radix_tree exceptional cases, mostly in filemap.c, clearer.

It's hard to devise a suitable snappy name that illuminates the use by
shmem/tmpfs for swap, while keeping filemap/pagecache/radix_tree
generality.  And akpm points out that /* radix_tree_deref_retry(page) */
comments look like calls that have been commented out for unknown
reason.

Skirt the naming difficulty by rearranging these blocks to handle the
transient radix_tree_deref_retry(page) case first; then just explain the
remaining shmem/tmpfs swap case in a comment.
Signed-off-by: default avatarHugh Dickins <hughd@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent e504f3fd
...@@ -700,10 +700,14 @@ struct page *find_get_page(struct address_space *mapping, pgoff_t offset) ...@@ -700,10 +700,14 @@ struct page *find_get_page(struct address_space *mapping, pgoff_t offset)
if (unlikely(!page)) if (unlikely(!page))
goto out; goto out;
if (radix_tree_exception(page)) { if (radix_tree_exception(page)) {
if (radix_tree_exceptional_entry(page)) if (radix_tree_deref_retry(page))
goto out; goto repeat;
/* radix_tree_deref_retry(page) */ /*
goto repeat; * Otherwise, shmem/tmpfs must be storing a swap entry
* here as an exceptional entry: so return it without
* attempting to raise page count.
*/
goto out;
} }
if (!page_cache_get_speculative(page)) if (!page_cache_get_speculative(page))
goto repeat; goto repeat;
...@@ -838,15 +842,21 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start, ...@@ -838,15 +842,21 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
continue; continue;
if (radix_tree_exception(page)) { if (radix_tree_exception(page)) {
if (radix_tree_exceptional_entry(page)) if (radix_tree_deref_retry(page)) {
continue; /*
* Transient condition which can only trigger
* when entry at index 0 moves out of or back
* to root: none yet gotten, safe to restart.
*/
WARN_ON(start | i);
goto restart;
}
/* /*
* radix_tree_deref_retry(page): * Otherwise, shmem/tmpfs must be storing a swap entry
* can only trigger when entry at index 0 moves out of * here as an exceptional entry: so skip over it -
* or back to root: none yet gotten, safe to restart. * we only reach this from invalidate_mapping_pages().
*/ */
WARN_ON(start | i); continue;
goto restart;
} }
if (!page_cache_get_speculative(page)) if (!page_cache_get_speculative(page))
...@@ -904,14 +914,20 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index, ...@@ -904,14 +914,20 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index,
continue; continue;
if (radix_tree_exception(page)) { if (radix_tree_exception(page)) {
if (radix_tree_exceptional_entry(page)) if (radix_tree_deref_retry(page)) {
break; /*
* Transient condition which can only trigger
* when entry at index 0 moves out of or back
* to root: none yet gotten, safe to restart.
*/
goto restart;
}
/* /*
* radix_tree_deref_retry(page): * Otherwise, shmem/tmpfs must be storing a swap entry
* can only trigger when entry at index 0 moves out of * here as an exceptional entry: so stop looking for
* or back to root: none yet gotten, safe to restart. * contiguous pages.
*/ */
goto restart; break;
} }
if (!page_cache_get_speculative(page)) if (!page_cache_get_speculative(page))
...@@ -973,13 +989,19 @@ unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, ...@@ -973,13 +989,19 @@ unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
continue; continue;
if (radix_tree_exception(page)) { if (radix_tree_exception(page)) {
BUG_ON(radix_tree_exceptional_entry(page)); if (radix_tree_deref_retry(page)) {
/*
* Transient condition which can only trigger
* when entry at index 0 moves out of or back
* to root: none yet gotten, safe to restart.
*/
goto restart;
}
/* /*
* radix_tree_deref_retry(page): * This function is never used on a shmem/tmpfs
* can only trigger when entry at index 0 moves out of * mapping, so a swap entry won't be found here.
* or back to root: none yet gotten, safe to restart.
*/ */
goto restart; BUG();
} }
if (!page_cache_get_speculative(page)) if (!page_cache_get_speculative(page))
......
...@@ -72,6 +72,7 @@ static unsigned char mincore_page(struct address_space *mapping, pgoff_t pgoff) ...@@ -72,6 +72,7 @@ static unsigned char mincore_page(struct address_space *mapping, pgoff_t pgoff)
*/ */
page = find_get_page(mapping, pgoff); page = find_get_page(mapping, pgoff);
#ifdef CONFIG_SWAP #ifdef CONFIG_SWAP
/* shmem/tmpfs may return swap: account for swapcache page too. */
if (radix_tree_exceptional_entry(page)) { if (radix_tree_exceptional_entry(page)) {
swp_entry_t swap = radix_to_swp_entry(page); swp_entry_t swap = radix_to_swp_entry(page);
page = find_get_page(&swapper_space, swap.val); page = find_get_page(&swapper_space, swap.val);
......
...@@ -332,10 +332,14 @@ static unsigned shmem_find_get_pages_and_swap(struct address_space *mapping, ...@@ -332,10 +332,14 @@ static unsigned shmem_find_get_pages_and_swap(struct address_space *mapping,
if (unlikely(!page)) if (unlikely(!page))
continue; continue;
if (radix_tree_exception(page)) { if (radix_tree_exception(page)) {
if (radix_tree_exceptional_entry(page)) if (radix_tree_deref_retry(page))
goto export; goto restart;
/* radix_tree_deref_retry(page) */ /*
goto restart; * Otherwise, we must be storing a swap entry
* here as an exceptional entry: so return it
* without attempting to raise page count.
*/
goto export;
} }
if (!page_cache_get_speculative(page)) if (!page_cache_get_speculative(page))
goto repeat; goto repeat;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment