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: Hugh Dickins <hughd@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
e504f3fdd6
commit
8079b1c859
66
mm/filemap.c
66
mm/filemap.c
@@ -700,10 +700,14 @@ repeat:
|
|||||||
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 @@ repeat:
|
|||||||
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 @@ repeat:
|
|||||||
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 @@ repeat:
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
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);
|
||||||
|
12
mm/shmem.c
12
mm/shmem.c
@@ -332,10 +332,14 @@ repeat:
|
|||||||
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;
|
||||||
|
Reference in New Issue
Block a user