[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230123173748.1734238-5-shr@devkernel.io>
Date: Mon, 23 Jan 2023 09:37:32 -0800
From: Stefan Roesch <shr@...kernel.io>
To: linux-mm@...ck.org
Cc: shr@...kernel.io, linux-doc@...r.kernel.org,
linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-kselftest@...r.kernel.org, linux-trace-kernel@...r.kernel.org
Subject: [RESEND RFC PATCH v1 04/20] mm: invoke madvise for all vmas in scan_get_next_rmap_item
If the new flag MMF_VM_MERGE_ANY has been set for a process, iterate
over all the vmas and enable ksm if possible. For the vmas that can be
ksm enabled this is only done once.
Signed-off-by: Stefan Roesch <shr@...kernel.io>
---
mm/ksm.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/mm/ksm.c b/mm/ksm.c
index 83796328574c..967eda719fab 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1013,6 +1013,7 @@ static int unmerge_and_remove_all_rmap_items(void)
mm_slot_free(mm_slot_cache, mm_slot);
clear_bit(MMF_VM_MERGEABLE, &mm->flags);
+ clear_bit(MMF_VM_MERGE_ANY, &mm->flags);
mmdrop(mm);
} else
spin_unlock(&ksm_mmlist_lock);
@@ -2243,6 +2244,17 @@ static struct ksm_rmap_item *get_next_rmap_item(struct ksm_mm_slot *mm_slot,
return rmap_item;
}
+static bool vma_ksm_mergeable(struct vm_area_struct *vma)
+{
+ if (vma->vm_flags & VM_MERGEABLE)
+ return true;
+
+ if (test_bit(MMF_VM_MERGE_ANY, &vma->vm_mm->flags))
+ return true;
+
+ return false;
+}
+
static struct ksm_rmap_item *scan_get_next_rmap_item(struct page **page)
{
struct mm_struct *mm;
@@ -2319,8 +2331,20 @@ static struct ksm_rmap_item *scan_get_next_rmap_item(struct page **page)
goto no_vmas;
for_each_vma(vmi, vma) {
- if (!(vma->vm_flags & VM_MERGEABLE))
+ if (!vma_ksm_mergeable(vma))
continue;
+ if (!(vma->vm_flags & VM_MERGEABLE)) {
+ unsigned long flags = vma->vm_flags;
+
+ /* madvise failed, use next vma */
+ if (ksm_madvise(vma, vma->vm_start, vma->vm_end, MADV_MERGEABLE, &flags))
+ continue;
+ /* vma, not supported as being mergeable */
+ if (!(flags & VM_MERGEABLE))
+ continue;
+
+ vma->vm_flags = flags;
+ }
if (ksm_scan.address < vma->vm_start)
ksm_scan.address = vma->vm_start;
if (!vma->anon_vma)
@@ -2389,6 +2413,7 @@ static struct ksm_rmap_item *scan_get_next_rmap_item(struct page **page)
mm_slot_free(mm_slot_cache, mm_slot);
clear_bit(MMF_VM_MERGEABLE, &mm->flags);
+ clear_bit(MMF_VM_MERGE_ANY, &mm->flags);
mmap_read_unlock(mm);
mmdrop(mm);
} else {
--
2.30.2
Powered by blists - more mailing lists