mirror of https://gitee.com/openkylin/linux.git
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: Nick Piggin <npiggin@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
0012818810
commit
45726cb43d
|
@ -621,26 +621,27 @@ struct page *find_lock_page(struct address_space *mapping,
|
|||
{
|
||||
struct page *page;
|
||||
|
||||
read_lock_irq(&mapping->tree_lock);
|
||||
repeat:
|
||||
read_lock_irq(&mapping->tree_lock);
|
||||
page = radix_tree_lookup(&mapping->page_tree, offset);
|
||||
if (page) {
|
||||
page_cache_get(page);
|
||||
if (TestSetPageLocked(page)) {
|
||||
read_unlock_irq(&mapping->tree_lock);
|
||||
__lock_page(page);
|
||||
read_lock_irq(&mapping->tree_lock);
|
||||
|
||||
/* Has the page been truncated while we slept? */
|
||||
if (unlikely(page->mapping != mapping ||
|
||||
page->index != offset)) {
|
||||
if (unlikely(page->mapping != mapping)) {
|
||||
unlock_page(page);
|
||||
page_cache_release(page);
|
||||
goto repeat;
|
||||
}
|
||||
VM_BUG_ON(page->index != offset);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
read_unlock_irq(&mapping->tree_lock);
|
||||
out:
|
||||
return page;
|
||||
}
|
||||
EXPORT_SYMBOL(find_lock_page);
|
||||
|
|
Loading…
Reference in New Issue