aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/futex.c
diff options
context:
space:
mode:
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>2016-01-15 19:53:00 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-15 20:56:32 -0500
commit14d27abd1d12a64c89df1ce8c00ef1403226db5a (patch)
tree57e38c2e06848b4c6998345d395b0c1b2f75b5d7 /kernel/futex.c
parentddc58f27f9eee9117219936f77e90ad5b2e00e96 (diff)
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 a5b338f2b0b1 ("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>
Diffstat (limited to 'kernel/futex.c')
-rw-r--r--kernel/futex.c63
1 files changed, 14 insertions, 49 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index 8a310e240cda..eed92a8a4c49 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -469,7 +469,8 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
469{ 469{
470 unsigned long address = (unsigned long)uaddr; 470 unsigned long address = (unsigned long)uaddr;
471 struct mm_struct *mm = current->mm; 471 struct mm_struct *mm = current->mm;
472 struct page *page, *page_head; 472 struct page *page;
473 struct address_space *mapping;
473 int err, ro = 0; 474 int err, ro = 0;
474 475
475 /* 476 /*
@@ -519,46 +520,9 @@ again:
519 else 520 else
520 err = 0; 521 err = 0;
521 522
522#ifdef CONFIG_TRANSPARENT_HUGEPAGE 523 lock_page(page);
523 page_head = page;
524 if (unlikely(PageTail(page))) {
525 put_page(page);
526 /* serialize against __split_huge_page_splitting() */
527 local_irq_disable();
528 if (likely(__get_user_pages_fast(address, 1, !ro, &page) == 1)) {
529 page_head = compound_head(page);
530 /*
531 * page_head is valid pointer but we must pin
532 * it before taking the PG_lock and/or
533 * PG_compound_lock. The moment we re-enable
534 * irqs __split_huge_page_splitting() can
535 * return and the head page can be freed from
536 * under us. We can't take the PG_lock and/or
537 * PG_compound_lock on a page that could be
538 * freed from under us.
539 */
540 if (page != page_head) {
541 get_page(page_head);
542 put_page(page);
543 }
544 local_irq_enable();
545 } else {
546 local_irq_enable();
547 goto again;
548 }
549 }
550#else
551 page_head = compound_head(page);
552 if (page != page_head) {
553 get_page(page_head);
554 put_page(page);
555 }
556#endif
557
558 lock_page(page_head);
559
560 /* 524 /*
561 * If page_head->mapping is NULL, then it cannot be a PageAnon 525 * If page->mapping is NULL, then it cannot be a PageAnon
562 * page; but it might be the ZERO_PAGE or in the gate area or 526 * page; but it might be the ZERO_PAGE or in the gate area or
563 * in a special mapping (all cases which we are happy to fail); 527 * in a special mapping (all cases which we are happy to fail);
564 * or it may have been a good file page when get_user_pages_fast 528 * or it may have been a good file page when get_user_pages_fast
@@ -570,12 +534,13 @@ again:
570 * 534 *
571 * The case we do have to guard against is when memory pressure made 535 * The case we do have to guard against is when memory pressure made
572 * shmem_writepage move it from filecache to swapcache beneath us: 536 * shmem_writepage move it from filecache to swapcache beneath us:
573 * an unlikely race, but we do need to retry for page_head->mapping. 537 * an unlikely race, but we do need to retry for page->mapping.
574 */ 538 */
575 if (!page_head->mapping) { 539 mapping = compound_head(page)->mapping;
576 int shmem_swizzled = PageSwapCache(page_head); 540 if (!mapping) {
577 unlock_page(page_head); 541 int shmem_swizzled = PageSwapCache(page);
578 put_page(page_head); 542 unlock_page(page);
543 put_page(page);
579 if (shmem_swizzled) 544 if (shmem_swizzled)
580 goto again; 545 goto again;
581 return -EFAULT; 546 return -EFAULT;
@@ -588,7 +553,7 @@ again:
588 * it's a read-only handle, it's expected that futexes attach to 553 * it's a read-only handle, it's expected that futexes attach to
589 * the object not the particular process. 554 * the object not the particular process.
590 */ 555 */
591 if (PageAnon(page_head)) { 556 if (PageAnon(page)) {
592 /* 557 /*
593 * A RO anonymous page will never change and thus doesn't make 558 * A RO anonymous page will never change and thus doesn't make
594 * sense for futex operations. 559 * sense for futex operations.
@@ -603,15 +568,15 @@ again:
603 key->private.address = address; 568 key->private.address = address;
604 } else { 569 } else {
605 key->both.offset |= FUT_OFF_INODE; /* inode-based key */ 570 key->both.offset |= FUT_OFF_INODE; /* inode-based key */
606 key->shared.inode = page_head->mapping->host; 571 key->shared.inode = mapping->host;
607 key->shared.pgoff = basepage_index(page); 572 key->shared.pgoff = basepage_index(page);
608 } 573 }
609 574
610 get_futex_key_refs(key); /* implies MB (B) */ 575 get_futex_key_refs(key); /* implies MB (B) */
611 576
612out: 577out:
613 unlock_page(page_head); 578 unlock_page(page);
614 put_page(page_head); 579 put_page(page);
615 return err; 580 return err;
616} 581}
617 582