futex, thp: remove special case for THP in get_futex_key
With new THP refcounting, we don't need tricks to stabilize huge page.
If we've got reference to tail page, it can't split under us.
This patch effectively reverts a5b338f2b0
("thp: update futex compound
knowledge").
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Tested-by: Sasha Levin <sasha.levin@oracle.com>
Tested-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Acked-by: Jerome Marchand <jmarchan@redhat.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Rik van Riel <riel@redhat.com>
Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Steve Capper <steve.capper@linaro.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Christoph Lameter <cl@linux.com>
Cc: David Rientjes <rientjes@google.com>
Tested-by: Artem Savkov <artem.savkov@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
ddc58f27f9
commit
14d27abd1d
|
@ -469,7 +469,8 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
|
|||
{
|
||||
unsigned long address = (unsigned long)uaddr;
|
||||
struct mm_struct *mm = current->mm;
|
||||
struct page *page, *page_head;
|
||||
struct page *page;
|
||||
struct address_space *mapping;
|
||||
int err, ro = 0;
|
||||
|
||||
/*
|
||||
|
@ -519,46 +520,9 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
|
|||
else
|
||||
err = 0;
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
page_head = page;
|
||||
if (unlikely(PageTail(page))) {
|
||||
put_page(page);
|
||||
/* serialize against __split_huge_page_splitting() */
|
||||
local_irq_disable();
|
||||
if (likely(__get_user_pages_fast(address, 1, !ro, &page) == 1)) {
|
||||
page_head = compound_head(page);
|
||||
/*
|
||||
* page_head is valid pointer but we must pin
|
||||
* it before taking the PG_lock and/or
|
||||
* PG_compound_lock. The moment we re-enable
|
||||
* irqs __split_huge_page_splitting() can
|
||||
* return and the head page can be freed from
|
||||
* under us. We can't take the PG_lock and/or
|
||||
* PG_compound_lock on a page that could be
|
||||
* freed from under us.
|
||||
*/
|
||||
if (page != page_head) {
|
||||
get_page(page_head);
|
||||
put_page(page);
|
||||
}
|
||||
local_irq_enable();
|
||||
} else {
|
||||
local_irq_enable();
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
#else
|
||||
page_head = compound_head(page);
|
||||
if (page != page_head) {
|
||||
get_page(page_head);
|
||||
put_page(page);
|
||||
}
|
||||
#endif
|
||||
|
||||
lock_page(page_head);
|
||||
|
||||
lock_page(page);
|
||||
/*
|
||||
* If page_head->mapping is NULL, then it cannot be a PageAnon
|
||||
* If page->mapping is NULL, then it cannot be a PageAnon
|
||||
* page; but it might be the ZERO_PAGE or in the gate area or
|
||||
* in a special mapping (all cases which we are happy to fail);
|
||||
* or it may have been a good file page when get_user_pages_fast
|
||||
|
@ -570,12 +534,13 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
|
|||
*
|
||||
* The case we do have to guard against is when memory pressure made
|
||||
* shmem_writepage move it from filecache to swapcache beneath us:
|
||||
* an unlikely race, but we do need to retry for page_head->mapping.
|
||||
* an unlikely race, but we do need to retry for page->mapping.
|
||||
*/
|
||||
if (!page_head->mapping) {
|
||||
int shmem_swizzled = PageSwapCache(page_head);
|
||||
unlock_page(page_head);
|
||||
put_page(page_head);
|
||||
mapping = compound_head(page)->mapping;
|
||||
if (!mapping) {
|
||||
int shmem_swizzled = PageSwapCache(page);
|
||||
unlock_page(page);
|
||||
put_page(page);
|
||||
if (shmem_swizzled)
|
||||
goto again;
|
||||
return -EFAULT;
|
||||
|
@ -588,7 +553,7 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
|
|||
* it's a read-only handle, it's expected that futexes attach to
|
||||
* the object not the particular process.
|
||||
*/
|
||||
if (PageAnon(page_head)) {
|
||||
if (PageAnon(page)) {
|
||||
/*
|
||||
* A RO anonymous page will never change and thus doesn't make
|
||||
* sense for futex operations.
|
||||
|
@ -603,15 +568,15 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
|
|||
key->private.address = address;
|
||||
} else {
|
||||
key->both.offset |= FUT_OFF_INODE; /* inode-based key */
|
||||
key->shared.inode = page_head->mapping->host;
|
||||
key->shared.inode = mapping->host;
|
||||
key->shared.pgoff = basepage_index(page);
|
||||
}
|
||||
|
||||
get_futex_key_refs(key); /* implies MB (B) */
|
||||
|
||||
out:
|
||||
unlock_page(page_head);
|
||||
put_page(page_head);
|
||||
unlock_page(page);
|
||||
put_page(page);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue