From: <zhouxianrong@huawei.com>
To: linux-mm@kvack.org
Cc: akpm@linux-foundation.org, hughd@google.com, aarcange@redhat.com,
kirill.shutemov@linux.intel.com, dave.hansen@linux.intel.com,
zhouchengming1@huawei.com, geliangtang@163.com,
zhouxianrong@huawei.com, linux-kernel@vger.kernel.org,
zhouxiyu@huawei.com, wanghaijun5@huawei.com
Subject: [PATCH] ksm: set anon_vma of first rmap_item of ksm page to page's anon_vma other than vma's anon_vma
Date: Thu, 23 Jun 2016 21:33:54 +0800 [thread overview]
Message-ID: <1466688834-127613-1-git-send-email-zhouxianrong@huawei.com> (raw)
From: z00281421 <z00281421@notesmail.huawei.com>
set anon_vma of first rmap_item of ksm page to page's anon_vma
other than vma's anon_vma so that we can lookup all the forked
vma of kpage via reserve map. thus we can try_to_unmap ksm page
completely and reclaim or migrate the ksm page successfully and
need not to merg other forked vma addresses of ksm page with
building a rmap_item for it ever after.
a forked more mapcount ksm page with partially merged vma addresses and
a ksm page mapped into non-VM_MERGEABLE vma due to setting MADV_MERGEABLE
on one of the forked vma can be unmapped completely by try_to_unmap.
Signed-off-by: z00281421 <z00281421@notesmail.huawei.com>
---
mm/ksm.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/mm/ksm.c b/mm/ksm.c
index 4786b41..6bacc08 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -971,11 +971,13 @@ out:
* @page: the PageAnon page that we want to replace with kpage
* @kpage: the PageKsm page that we want to map instead of page,
* or NULL the first time when we want to use page as kpage.
+ * @anon_vma: output the anon_vma of page used as kpage
*
* This function returns 0 if the pages were merged, -EFAULT otherwise.
*/
static int try_to_merge_one_page(struct vm_area_struct *vma,
- struct page *page, struct page *kpage)
+ struct page *page, struct page *kpage,
+ struct anon_vma **anon_vma)
{
pte_t orig_pte = __pte(0);
int err = -EFAULT;
@@ -1015,6 +1017,8 @@ static int try_to_merge_one_page(struct vm_area_struct *vma,
* PageAnon+anon_vma to PageKsm+NULL stable_node:
* stable_tree_insert() will update stable_node.
*/
+ if (anon_vma != NULL)
+ *anon_vma = page_anon_vma(page);
set_page_stable_node(page, NULL);
mark_page_accessed(page);
/*
@@ -1055,6 +1059,7 @@ static int try_to_merge_with_ksm_page(struct rmap_item *rmap_item,
{
struct mm_struct *mm = rmap_item->mm;
struct vm_area_struct *vma;
+ struct anon_vma *anon_vma = NULL;
int err = -EFAULT;
down_read(&mm->mmap_sem);
@@ -1062,7 +1067,7 @@ static int try_to_merge_with_ksm_page(struct rmap_item *rmap_item,
if (!vma)
goto out;
- err = try_to_merge_one_page(vma, page, kpage);
+ err = try_to_merge_one_page(vma, page, kpage, &anon_vma);
if (err)
goto out;
@@ -1070,7 +1075,10 @@ static int try_to_merge_with_ksm_page(struct rmap_item *rmap_item,
remove_rmap_item_from_tree(rmap_item);
/* Must get reference to anon_vma while still holding mmap_sem */
- rmap_item->anon_vma = vma->anon_vma;
+ if (anon_vma != NULL)
+ rmap_item->anon_vma = anon_vma;
+ else
+ rmap_item->anon_vma = vma->anon_vma;
get_anon_vma(vma->anon_vma);
out:
up_read(&mm->mmap_sem);
@@ -1435,6 +1443,11 @@ static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item)
remove_rmap_item_from_tree(rmap_item);
+ if (kpage == page) {
+ put_page(kpage);
+ return;
+ }
+
if (kpage) {
err = try_to_merge_with_ksm_page(rmap_item, page, kpage);
if (!err) {
--
1.7.9.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next reply other threads:[~2016-06-23 13:37 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-23 13:33 zhouxianrong [this message]
2016-06-23 23:49 ` Andrew Morton
2016-07-20 0:42 ` Hugh Dickins
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1466688834-127613-1-git-send-email-zhouxianrong@huawei.com \
--to=zhouxianrong@huawei.com \
--cc=aarcange@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=dave.hansen@linux.intel.com \
--cc=geliangtang@163.com \
--cc=hughd@google.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=wanghaijun5@huawei.com \
--cc=zhouchengming1@huawei.com \
--cc=zhouxiyu@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox