aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/futex.c
diff options
context:
space:
mode:
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