Commit 45726cb4 authored by Nick Piggin's avatar Nick Piggin Committed by Linus Torvalds

mm: improve find_lock_page

find_lock_page does not need to recheck ->index because if the page is in the
right mapping then the index must be the same.  Also, tree_lock does not need
to be retaken after the page is locked in order to test that ->mapping has not
changed, because holding the page lock pins its mapping.
Signed-off-by: default avatarNick Piggin <npiggin@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 00128188
...@@ -621,26 +621,27 @@ struct page *find_lock_page(struct address_space *mapping, ...@@ -621,26 +621,27 @@ struct page *find_lock_page(struct address_space *mapping,
{ {
struct page *page; struct page *page;
read_lock_irq(&mapping->tree_lock);
repeat: repeat:
read_lock_irq(&mapping->tree_lock);
page = radix_tree_lookup(&mapping->page_tree, offset); page = radix_tree_lookup(&mapping->page_tree, offset);
if (page) { if (page) {
page_cache_get(page); page_cache_get(page);
if (TestSetPageLocked(page)) { if (TestSetPageLocked(page)) {
read_unlock_irq(&mapping->tree_lock); read_unlock_irq(&mapping->tree_lock);
__lock_page(page); __lock_page(page);
read_lock_irq(&mapping->tree_lock);
/* Has the page been truncated while we slept? */ /* Has the page been truncated while we slept? */
if (unlikely(page->mapping != mapping || if (unlikely(page->mapping != mapping)) {
page->index != offset)) {
unlock_page(page); unlock_page(page);
page_cache_release(page); page_cache_release(page);
goto repeat; goto repeat;
} }
VM_BUG_ON(page->index != offset);
goto out;
} }
} }
read_unlock_irq(&mapping->tree_lock); read_unlock_irq(&mapping->tree_lock);
out:
return page; return page;
} }
EXPORT_SYMBOL(find_lock_page); EXPORT_SYMBOL(find_lock_page);
......
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