hugetlb, rmap: fix confusing page locking in hugetlb_cow()

The "if (!trylock_page)" block in the avoidcopy path of hugetlb_cow()
looks confusing and is buggy. Originally this trylock_page() was
intended to make sure that old_page is locked even when old_page !=
pagecache_page, because then only pagecache_page is locked.

This patch fixes it by moving page locking into hugetlb_fault().

Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Acked-by: Rik van Riel <riel@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Naoya Horiguchi and committed by Linus Torvalds 56c9cfb1 cd67f0d2

+12 -10
+12 -10
mm/hugetlb.c
··· 2324 2324 * and just make the page writable */ 2325 2325 avoidcopy = (page_mapcount(old_page) == 1); 2326 2326 if (avoidcopy) { 2327 - if (!trylock_page(old_page)) { 2328 - if (PageAnon(old_page)) 2329 - page_move_anon_rmap(old_page, vma, address); 2330 - } else 2331 - unlock_page(old_page); 2327 + if (PageAnon(old_page)) 2328 + page_move_anon_rmap(old_page, vma, address); 2332 2329 set_huge_ptep_writable(vma, address, ptep); 2333 2330 return 0; 2334 2331 } ··· 2628 2631 vma, address); 2629 2632 } 2630 2633 2631 - if (!pagecache_page) { 2632 - page = pte_page(entry); 2634 + /* 2635 + * hugetlb_cow() requires page locks of pte_page(entry) and 2636 + * pagecache_page, so here we need take the former one 2637 + * when page != pagecache_page or !pagecache_page. 2638 + * Note that locking order is always pagecache_page -> page, 2639 + * so no worry about deadlock. 2640 + */ 2641 + page = pte_page(entry); 2642 + if (page != pagecache_page) 2633 2643 lock_page(page); 2634 - } 2635 2644 2636 2645 spin_lock(&mm->page_table_lock); 2637 2646 /* Check for a racing update before calling hugetlb_cow */ ··· 2664 2661 if (pagecache_page) { 2665 2662 unlock_page(pagecache_page); 2666 2663 put_page(pagecache_page); 2667 - } else { 2668 - unlock_page(page); 2669 2664 } 2665 + unlock_page(page); 2670 2666 2671 2667 out_mutex: 2672 2668 mutex_unlock(&hugetlb_instantiation_mutex);