aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>2016-01-15 19:53:03 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-15 20:56:32 -0500
commitf765f540598a129dc4bb6f698fd4acc92f296c14 (patch)
treec7d11ce64f3849985a56412ffd543f0d419d2deb
parent14d27abd1d12a64c89df1ce8c00ef1403226db5a (diff)
ksm: prepare to new THP semantics
We don't need special code to stabilize THP. If you've got reference to any subpage of THP it will not be split under you. New split_huge_page() also accepts tail pages: no need in special code to get reference to head page. 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: Vlastimil Babka <vbabka@suse.cz> Acked-by: Jerome Marchand <jmarchan@redhat.com> 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> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/ksm.c57
1 files changed, 10 insertions, 47 deletions
diff --git a/mm/ksm.c b/mm/ksm.c
index b4f7b69efad0..80c29b1b2b8a 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -441,20 +441,6 @@ static void break_cow(struct rmap_item *rmap_item)
441 up_read(&mm->mmap_sem); 441 up_read(&mm->mmap_sem);
442} 442}
443 443
444static struct page *page_trans_compound_anon(struct page *page)
445{
446 if (PageTransCompound(page)) {
447 struct page *head = compound_head(page);
448 /*
449 * head may actually be splitted and freed from under
450 * us but it's ok here.
451 */
452 if (PageAnon(head))
453 return head;
454 }
455 return NULL;
456}
457
458static struct page *get_mergeable_page(struct rmap_item *rmap_item) 444static struct page *get_mergeable_page(struct rmap_item *rmap_item)
459{ 445{
460 struct mm_struct *mm = rmap_item->mm; 446 struct mm_struct *mm = rmap_item->mm;
@@ -470,7 +456,7 @@ static struct page *get_mergeable_page(struct rmap_item *rmap_item)
470 page = follow_page(vma, addr, FOLL_GET); 456 page = follow_page(vma, addr, FOLL_GET);
471 if (IS_ERR_OR_NULL(page)) 457 if (IS_ERR_OR_NULL(page))
472 goto out; 458 goto out;
473 if (PageAnon(page) || page_trans_compound_anon(page)) { 459 if (PageAnon(page)) {
474 flush_anon_page(vma, page, addr); 460 flush_anon_page(vma, page, addr);
475 flush_dcache_page(page); 461 flush_dcache_page(page);
476 } else { 462 } else {
@@ -975,33 +961,6 @@ out:
975 return err; 961 return err;
976} 962}
977 963
978static int page_trans_compound_anon_split(struct page *page)
979{
980 int ret = 0;
981 struct page *transhuge_head = page_trans_compound_anon(page);
982 if (transhuge_head) {
983 /* Get the reference on the head to split it. */
984 if (get_page_unless_zero(transhuge_head)) {
985 /*
986 * Recheck we got the reference while the head
987 * was still anonymous.
988 */
989 if (PageAnon(transhuge_head))
990 ret = split_huge_page(transhuge_head);
991 else
992 /*
993 * Retry later if split_huge_page run
994 * from under us.
995 */
996 ret = 1;
997 put_page(transhuge_head);
998 } else
999 /* Retry later if split_huge_page run from under us. */
1000 ret = 1;
1001 }
1002 return ret;
1003}
1004
1005/* 964/*
1006 * try_to_merge_one_page - take two pages and merge them into one 965 * try_to_merge_one_page - take two pages and merge them into one
1007 * @vma: the vma that holds the pte pointing to page 966 * @vma: the vma that holds the pte pointing to page
@@ -1020,9 +979,6 @@ static int try_to_merge_one_page(struct vm_area_struct *vma,
1020 if (page == kpage) /* ksm page forked */ 979 if (page == kpage) /* ksm page forked */
1021 return 0; 980 return 0;
1022 981
1023 if (PageTransCompound(page) && page_trans_compound_anon_split(page))
1024 goto out;
1025 BUG_ON(PageTransCompound(page));
1026 if (!PageAnon(page)) 982 if (!PageAnon(page))
1027 goto out; 983 goto out;
1028 984
@@ -1035,6 +991,13 @@ static int try_to_merge_one_page(struct vm_area_struct *vma,
1035 */ 991 */
1036 if (!trylock_page(page)) 992 if (!trylock_page(page))
1037 goto out; 993 goto out;
994
995 if (PageTransCompound(page)) {
996 err = split_huge_page(page);
997 if (err)
998 goto out_unlock;
999 }
1000
1038 /* 1001 /*
1039 * If this anonymous page is mapped only here, its pte may need 1002 * If this anonymous page is mapped only here, its pte may need
1040 * to be write-protected. If it's mapped elsewhere, all of its 1003 * to be write-protected. If it's mapped elsewhere, all of its
@@ -1065,6 +1028,7 @@ static int try_to_merge_one_page(struct vm_area_struct *vma,
1065 } 1028 }
1066 } 1029 }
1067 1030
1031out_unlock:
1068 unlock_page(page); 1032 unlock_page(page);
1069out: 1033out:
1070 return err; 1034 return err;
@@ -1635,8 +1599,7 @@ next_mm:
1635 cond_resched(); 1599 cond_resched();
1636 continue; 1600 continue;
1637 } 1601 }
1638 if (PageAnon(*page) || 1602 if (PageAnon(*page)) {
1639 page_trans_compound_anon(*page)) {
1640 flush_anon_page(vma, *page, ksm_scan.address); 1603 flush_anon_page(vma, *page, ksm_scan.address);
1641 flush_dcache_page(*page); 1604 flush_dcache_page(*page);
1642 rmap_item = get_next_rmap_item(slot, 1605 rmap_item = get_next_rmap_item(slot,