Commit f765f540 authored by Kirill A. Shutemov's avatar Kirill A. Shutemov Committed by Linus Torvalds

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: default avatarKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Tested-by: default avatarSasha Levin <sasha.levin@oracle.com>
Tested-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Acked-by: default avatarVlastimil Babka <vbabka@suse.cz>
Acked-by: default avatarJerome 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 14d27abd
...@@ -441,20 +441,6 @@ static void break_cow(struct rmap_item *rmap_item) ...@@ -441,20 +441,6 @@ static void break_cow(struct rmap_item *rmap_item)
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
} }
static struct page *page_trans_compound_anon(struct page *page)
{
if (PageTransCompound(page)) {
struct page *head = compound_head(page);
/*
* head may actually be splitted and freed from under
* us but it's ok here.
*/
if (PageAnon(head))
return head;
}
return NULL;
}
static struct page *get_mergeable_page(struct rmap_item *rmap_item) static struct page *get_mergeable_page(struct rmap_item *rmap_item)
{ {
struct mm_struct *mm = rmap_item->mm; struct mm_struct *mm = rmap_item->mm;
...@@ -470,7 +456,7 @@ static struct page *get_mergeable_page(struct rmap_item *rmap_item) ...@@ -470,7 +456,7 @@ static struct page *get_mergeable_page(struct rmap_item *rmap_item)
page = follow_page(vma, addr, FOLL_GET); page = follow_page(vma, addr, FOLL_GET);
if (IS_ERR_OR_NULL(page)) if (IS_ERR_OR_NULL(page))
goto out; goto out;
if (PageAnon(page) || page_trans_compound_anon(page)) { if (PageAnon(page)) {
flush_anon_page(vma, page, addr); flush_anon_page(vma, page, addr);
flush_dcache_page(page); flush_dcache_page(page);
} else { } else {
...@@ -975,33 +961,6 @@ static int replace_page(struct vm_area_struct *vma, struct page *page, ...@@ -975,33 +961,6 @@ static int replace_page(struct vm_area_struct *vma, struct page *page,
return err; return err;
} }
static int page_trans_compound_anon_split(struct page *page)
{
int ret = 0;
struct page *transhuge_head = page_trans_compound_anon(page);
if (transhuge_head) {
/* Get the reference on the head to split it. */
if (get_page_unless_zero(transhuge_head)) {
/*
* Recheck we got the reference while the head
* was still anonymous.
*/
if (PageAnon(transhuge_head))
ret = split_huge_page(transhuge_head);
else
/*
* Retry later if split_huge_page run
* from under us.
*/
ret = 1;
put_page(transhuge_head);
} else
/* Retry later if split_huge_page run from under us. */
ret = 1;
}
return ret;
}
/* /*
* try_to_merge_one_page - take two pages and merge them into one * try_to_merge_one_page - take two pages and merge them into one
* @vma: the vma that holds the pte pointing to page * @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,9 +979,6 @@ static int try_to_merge_one_page(struct vm_area_struct *vma,
if (page == kpage) /* ksm page forked */ if (page == kpage) /* ksm page forked */
return 0; return 0;
if (PageTransCompound(page) && page_trans_compound_anon_split(page))
goto out;
BUG_ON(PageTransCompound(page));
if (!PageAnon(page)) if (!PageAnon(page))
goto out; goto out;
...@@ -1035,6 +991,13 @@ static int try_to_merge_one_page(struct vm_area_struct *vma, ...@@ -1035,6 +991,13 @@ static int try_to_merge_one_page(struct vm_area_struct *vma,
*/ */
if (!trylock_page(page)) if (!trylock_page(page))
goto out; goto out;
if (PageTransCompound(page)) {
err = split_huge_page(page);
if (err)
goto out_unlock;
}
/* /*
* If this anonymous page is mapped only here, its pte may need * If this anonymous page is mapped only here, its pte may need
* to be write-protected. If it's mapped elsewhere, all of its * 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,6 +1028,7 @@ static int try_to_merge_one_page(struct vm_area_struct *vma,
} }
} }
out_unlock:
unlock_page(page); unlock_page(page);
out: out:
return err; return err;
...@@ -1635,8 +1599,7 @@ static struct rmap_item *scan_get_next_rmap_item(struct page **page) ...@@ -1635,8 +1599,7 @@ static struct rmap_item *scan_get_next_rmap_item(struct page **page)
cond_resched(); cond_resched();
continue; continue;
} }
if (PageAnon(*page) || if (PageAnon(*page)) {
page_trans_compound_anon(*page)) {
flush_anon_page(vma, *page, ksm_scan.address); flush_anon_page(vma, *page, ksm_scan.address);
flush_dcache_page(*page); flush_dcache_page(*page);
rmap_item = get_next_rmap_item(slot, rmap_item = get_next_rmap_item(slot,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment