[PATCH 04/14] mm/ksm: add advance_scan_mm_slot() helper
From: Longlong Xia
Date: Tue Sep 15 2026 - 11:15:53 EST
From: Longlong Xia <xialonglong@xxxxxxxxxx>
Factor the four mm-slot cursor advances in scan_get_next_rmap_item()
and unmerge_and_remove_all_rmap_items() into a helper. Assert that
ksm_mmlist_lock is held.
No functional change intended.
Assisted-by: Zcode:GLM-5.3
Signed-off-by: Longlong Xia <xialonglong@xxxxxxxxxx>
---
mm/ksm.c | 34 ++++++++++++++++++++--------------
1 file changed, 20 insertions(+), 14 deletions(-)
diff --git a/mm/ksm.c b/mm/ksm.c
index 18d037f571d3..aa33522627c7 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1119,6 +1119,22 @@ static inline void folio_set_stable_node(struct folio *folio,
(void *)((unsigned long)stable_node | FOLIO_MAPPING_KSM));
}
+/*
+ * Move the ksmd cursor onto the mm slot that follows @mm_slot in the
+ * ksm_mm_head list, and return the new cursor (@mm_slot may be
+ * &ksm_mm_head to (re)start from the first slot). Called with
+ * ksm_mmlist_lock held.
+ */
+static struct ksm_mm_slot *advance_scan_mm_slot(struct ksm_mm_slot *mm_slot)
+{
+ struct mm_slot *slot;
+
+ lockdep_assert_held(&ksm_mmlist_lock);
+ slot = list_entry(mm_slot->slot.mm_node.next, struct mm_slot, mm_node);
+ ksm_scan.mm_slot = mm_slot_entry(slot, struct ksm_mm_slot, slot);
+ return ksm_scan.mm_slot;
+}
+
#ifdef CONFIG_SYSFS
/*
* Only called through the sysfs control interface:
@@ -1215,15 +1231,12 @@ static int remove_all_stable_nodes(void)
static int unmerge_and_remove_all_rmap_items(void)
{
struct ksm_mm_slot *mm_slot;
- struct mm_slot *slot;
struct mm_struct *mm;
struct vm_area_struct *vma;
int err = 0;
spin_lock(&ksm_mmlist_lock);
- slot = list_entry(ksm_mm_head.slot.mm_node.next,
- struct mm_slot, mm_node);
- ksm_scan.mm_slot = mm_slot_entry(slot, struct ksm_mm_slot, slot);
+ advance_scan_mm_slot(&ksm_mm_head);
spin_unlock(&ksm_mmlist_lock);
for (mm_slot = ksm_scan.mm_slot; mm_slot != &ksm_mm_head;
@@ -1253,9 +1266,7 @@ static int unmerge_and_remove_all_rmap_items(void)
mmap_read_unlock(mm);
spin_lock(&ksm_mmlist_lock);
- slot = list_entry(mm_slot->slot.mm_node.next,
- struct mm_slot, mm_node);
- ksm_scan.mm_slot = mm_slot_entry(slot, struct ksm_mm_slot, slot);
+ advance_scan_mm_slot(mm_slot);
if (ksm_test_exit(mm)) {
mm_slot_remove(&mm_slot->slot);
spin_unlock(&ksm_mmlist_lock);
@@ -2662,10 +2673,7 @@ static struct ksm_rmap_item *scan_get_next_rmap_item(struct page **page)
root_unstable_tree[nid] = RB_ROOT;
spin_lock(&ksm_mmlist_lock);
- slot = list_entry(mm_slot->slot.mm_node.next,
- struct mm_slot, mm_node);
- mm_slot = mm_slot_entry(slot, struct ksm_mm_slot, slot);
- ksm_scan.mm_slot = mm_slot;
+ mm_slot = advance_scan_mm_slot(mm_slot);
spin_unlock(&ksm_mmlist_lock);
/*
* Although we tested list_empty() above, a racing __ksm_exit
@@ -2758,9 +2766,7 @@ static struct ksm_rmap_item *scan_get_next_rmap_item(struct page **page)
remove_trailing_rmap_items(ksm_scan.rmap_list);
spin_lock(&ksm_mmlist_lock);
- slot = list_entry(mm_slot->slot.mm_node.next,
- struct mm_slot, mm_node);
- ksm_scan.mm_slot = mm_slot_entry(slot, struct ksm_mm_slot, slot);
+ advance_scan_mm_slot(mm_slot);
if (ksm_scan.address == 0) {
/*
* We've completed a full scan of all vmas, holding mmap_lock
--
2.43.0