Re: [PATCH v8 14/21] mm/mmap: Avoid zeroing vma tree in mmap_region()

Lorenzo Stoakes
2024-10-04T08:37:14Z

Hey Bert,

Sorry to bother you again, but would it be possible to try the v5 patch
below?

This one should eliminate the need for you to set the no_hash_pointers
cmdline setting.

Sadly it seems I can't fully recreate the tree or confirm it without
disabling this hashing.

Thanks, as usual all of your help is much appreciated!

Best, Lorenzo

----8<----
From f7d1f54ffd166a52b2ae0ce94c99259aefd80521 Mon Sep 17 00:00:00 2001
From: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Date: Thu, 3 Oct 2024 14:19:17 +0100
Subject: [PATCH] hack: set of info stuff v5

Try to dump the maple tree immediately prior to it exploding so we can see
how things are before/after + try to reconstruct.

Also do not hash pointers in tree dump...
---
lib/maple_tree.c | 74 ++++++++++++++++++-------------------
mm/internal.h | 15 ++++++++
mm/mmap.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++-
mm/vma.c | 51 ++++++++++++++++++++++++--
4 files changed, 194 insertions(+), 41 deletions(-)

diff --git a/lib/maple_tree.c b/lib/maple_tree.c
index 37abf0fe380b..0b7064ee8f39 100644
--- a/lib/maple_tree.c
+++ b/lib/maple_tree.c
@@ -7119,14 +7119,14 @@ static void mt_dump_entry(void *entry, unsigned long min, unsigned long max,
mt_dump_range(min, max, depth, format);

if (xa_is_value(entry))
- pr_cont("value %ld (0x%lx) [%p]\n", xa_to_value(entry),
+ pr_cont("value %ld (0x%lx) [%px]\n", xa_to_value(entry),
xa_to_value(entry), entry);
else if (xa_is_zero(entry))
pr_cont("zero (%ld)\n", xa_to_internal(entry));
else if (mt_is_reserved(entry))
- pr_cont("UNKNOWN ENTRY (%p)\n", entry);
+ pr_cont("UNKNOWN ENTRY (%px)\n", entry);
else
- pr_cont("%p\n", entry);
+ pr_cont("%px\n", entry);
}

static void mt_dump_range64(const struct maple_tree *mt, void *entry,
@@ -7142,13 +7142,13 @@ static void mt_dump_range64(const struct maple_tree *mt, void *entry,
for (i = 0; i < MAPLE_RANGE64_SLOTS - 1; i++) {
switch(format) {
case mt_dump_hex:
- pr_cont("%p %lX ", node->slot[i], node->pivot[i]);
+ pr_cont("%px %lX ", node->slot[i], node->pivot[i]);
break;
case mt_dump_dec:
- pr_cont("%p %lu ", node->slot[i], node->pivot[i]);
+ pr_cont("%px %lu ", node->slot[i], node->pivot[i]);
}
}
- pr_cont("%p\n", node->slot[i]);
+ pr_cont("%px\n", node->slot[i]);
for (i = 0; i < MAPLE_RANGE64_SLOTS; i++) {
unsigned long last = max;

@@ -7170,11 +7170,11 @@ static void mt_dump_range64(const struct maple_tree *mt, void *entry,
if (last > max) {
switch(format) {
case mt_dump_hex:
- pr_err("node %p last (%lx) > max (%lx) at pivot %d!\n",
+ pr_err("node %px last (%lx) > max (%lx) at pivot %d!\n",
node, last, max, i);
break;
case mt_dump_dec:
- pr_err("node %p last (%lu) > max (%lu) at pivot %d!\n",
+ pr_err("node %px last (%lu) > max (%lu) at pivot %d!\n",
node, last, max, i);
}
}
@@ -7204,13 +7204,13 @@ static void mt_dump_arange64(const struct maple_tree *mt, void *entry,
for (i = 0; i < MAPLE_ARANGE64_SLOTS - 1; i++) {
switch (format) {
case mt_dump_hex:
- pr_cont("%p %lX ", node->slot[i], node->pivot[i]);
+ pr_cont("%px %lX ", node->slot[i], node->pivot[i]);
break;
case mt_dump_dec:
- pr_cont("%p %lu ", node->slot[i], node->pivot[i]);
+ pr_cont("%px %lu ", node->slot[i], node->pivot[i]);
}
}
- pr_cont("%p\n", node->slot[i]);
+ pr_cont("%px\n", node->slot[i]);
for (i = 0; i < MAPLE_ARANGE64_SLOTS; i++) {
unsigned long last = max;

@@ -7229,11 +7229,11 @@ static void mt_dump_arange64(const struct maple_tree *mt, void *entry,
if (last > max) {
switch(format) {
case mt_dump_hex:
- pr_err("node %p last (%lx) > max (%lx) at pivot %d!\n",
+ pr_err("node %px last (%lx) > max (%lx) at pivot %d!\n",
node, last, max, i);
break;
case mt_dump_dec:
- pr_err("node %p last (%lu) > max (%lu) at pivot %d!\n",
+ pr_err("node %px last (%lu) > max (%lu) at pivot %d!\n",
node, last, max, i);
}
}
@@ -7251,7 +7251,7 @@ static void mt_dump_node(const struct maple_tree *mt, void *entry,

mt_dump_range(min, max, depth, format);

- pr_cont("node %p depth %d type %d parent %p", node, depth, type,
+ pr_cont("node %px depth %d type %d parent %px", node, depth, type,
node ? node->parent : NULL);
switch (type) {
case maple_dense:
@@ -7280,7 +7280,7 @@ void mt_dump(const struct maple_tree *mt, enum mt_dump_format format)
{
void *entry = rcu_dereference_check(mt->ma_root, mt_locked(mt));

- pr_info("maple_tree(%p) flags %X, height %u root %p\n",
+ pr_info("maple_tree(%px) flags %X, height %u root %px\n",
mt, mt->ma_flags, mt_height(mt), entry);
if (!xa_is_node(entry))
mt_dump_entry(entry, 0, 0, 0, format);
@@ -7332,7 +7332,7 @@ static void mas_validate_gaps(struct ma_state *mas)
MT_BUG_ON(mas->tree, !entry);

if (gap > p_end - p_start + 1) {
- pr_err("%p[%u] %lu >= %lu - %lu + 1 (%lu)\n",
+ pr_err("%px[%u] %lu >= %lu - %lu + 1 (%lu)\n",
mas_mn(mas), i, gap, p_end, p_start,
p_end - p_start + 1);
MT_BUG_ON(mas->tree, gap > p_end - p_start + 1);
@@ -7352,19 +7352,19 @@ static void mas_validate_gaps(struct ma_state *mas)
MT_BUG_ON(mas->tree, !gaps);
offset = ma_meta_gap(node);
if (offset > i) {
- pr_err("gap offset %p[%u] is invalid\n", node, offset);
+ pr_err("gap offset %px[%u] is invalid\n", node, offset);
MT_BUG_ON(mas->tree, 1);
}

if (gaps[offset] != max_gap) {
- pr_err("gap %p[%u] is not the largest gap %lu\n",
+ pr_err("gap %px[%u] is not the largest gap %lu\n",
node, offset, max_gap);
MT_BUG_ON(mas->tree, 1);
}

for (i++ ; i < mt_slot_count(mte); i++) {
if (gaps[i] != 0) {
- pr_err("gap %p[%u] beyond node limit != 0\n",
+ pr_err("gap %px[%u] beyond node limit != 0\n",
node, i);
MT_BUG_ON(mas->tree, 1);
}
@@ -7378,7 +7378,7 @@ static void mas_validate_gaps(struct ma_state *mas)
p_mn = mte_parent(mte);
MT_BUG_ON(mas->tree, max_gap > mas->max);
if (ma_gaps(p_mn, mas_parent_type(mas, mte))[p_slot] != max_gap) {
- pr_err("gap %p[%u] != %lu\n", p_mn, p_slot, max_gap);
+ pr_err("gap %px[%u] != %lu\n", p_mn, p_slot, max_gap);
mt_dump(mas->tree, mt_dump_hex);
MT_BUG_ON(mas->tree, 1);
}
@@ -7408,11 +7408,11 @@ static void mas_validate_parent_slot(struct ma_state *mas)
node = mas_slot(mas, slots, i);
if (i == p_slot) {
if (node != mas->node)
- pr_err("parent %p[%u] does not have %p\n",
+ pr_err("parent %px[%u] does not have %px\n",
parent, i, mas_mn(mas));
MT_BUG_ON(mas->tree, node != mas->node);
} else if (node == mas->node) {
- pr_err("Invalid child %p at parent %p[%u] p_slot %u\n",
+ pr_err("Invalid child %px at parent %px[%u] p_slot %u\n",
mas_mn(mas), parent, i, p_slot);
MT_BUG_ON(mas->tree, node == mas->node);
}
@@ -7434,20 +7434,20 @@ static void mas_validate_child_slot(struct ma_state *mas)
child = mas_slot(mas, slots, i);

if (!child) {
- pr_err("Non-leaf node lacks child at %p[%u]\n",
+ pr_err("Non-leaf node lacks child at %px[%u]\n",
mas_mn(mas), i);
MT_BUG_ON(mas->tree, 1);
}

if (mte_parent_slot(child) != i) {
- pr_err("Slot error at %p[%u]: child %p has pslot %u\n",
+ pr_err("Slot error at %px[%u]: child %px has pslot %u\n",
mas_mn(mas), i, mte_to_node(child),
mte_parent_slot(child));
MT_BUG_ON(mas->tree, 1);
}

if (mte_parent(child) != mte_to_node(mas->node)) {
- pr_err("child %p has parent %p not %p\n",
+ pr_err("child %px has parent %px not %px\n",
mte_to_node(child), mte_parent(child),
mte_to_node(mas->node));
MT_BUG_ON(mas->tree, 1);
@@ -7477,24 +7477,24 @@ static void mas_validate_limits(struct ma_state *mas)
piv = mas_safe_pivot(mas, pivots, i, type);

if (!piv && (i != 0)) {
- pr_err("Missing node limit pivot at %p[%u]",
+ pr_err("Missing node limit pivot at %px[%u]",
mas_mn(mas), i);
MAS_WARN_ON(mas, 1);
}

if (prev_piv > piv) {
- pr_err("%p[%u] piv %lu < prev_piv %lu\n",
+ pr_err("%px[%u] piv %lu < prev_piv %lu\n",
mas_mn(mas), i, piv, prev_piv);
MAS_WARN_ON(mas, piv < prev_piv);
}

if (piv < mas->min) {
- pr_err("%p[%u] %lu < %lu\n", mas_mn(mas), i,
+ pr_err("%px[%u] %lu < %lu\n", mas_mn(mas), i,
piv, mas->min);
MAS_WARN_ON(mas, piv < mas->min);
}
if (piv > mas->max) {
- pr_err("%p[%u] %lu > %lu\n", mas_mn(mas), i,
+ pr_err("%px[%u] %lu > %lu\n", mas_mn(mas), i,
piv, mas->max);
MAS_WARN_ON(mas, piv > mas->max);
}
@@ -7504,7 +7504,7 @@ static void mas_validate_limits(struct ma_state *mas)
}

if (mas_data_end(mas) != i) {
- pr_err("node%p: data_end %u != the last slot offset %u\n",
+ pr_err("node%px: data_end %u != the last slot offset %u\n",
mas_mn(mas), mas_data_end(mas), i);
MT_BUG_ON(mas->tree, 1);
}
@@ -7513,7 +7513,7 @@ static void mas_validate_limits(struct ma_state *mas)
void *entry = mas_slot(mas, slots, i);

if (entry && (i != mt_slots[type] - 1)) {
- pr_err("%p[%u] should not have entry %p\n", mas_mn(mas),
+ pr_err("%px[%u] should not have entry %px\n", mas_mn(mas),
i, entry);
MT_BUG_ON(mas->tree, entry != NULL);
}
@@ -7524,7 +7524,7 @@ static void mas_validate_limits(struct ma_state *mas)
if (!piv)
continue;

- pr_err("%p[%u] should not have piv %lu\n",
+ pr_err("%px[%u] should not have piv %lu\n",
mas_mn(mas), i, piv);
MAS_WARN_ON(mas, i < mt_pivots[type] - 1);
}
@@ -7549,7 +7549,7 @@ static void mt_validate_nulls(struct maple_tree *mt)
do {
entry = mas_slot(&mas, slots, offset);
if (!last && !entry) {
- pr_err("Sequential nulls end at %p[%u]\n",
+ pr_err("Sequential nulls end at %px[%u]\n",
mas_mn(&mas), offset);
}
MT_BUG_ON(mt, !last && !entry);
@@ -7591,7 +7591,7 @@ void mt_validate(struct maple_tree *mt)
end = mas_data_end(&mas);
if (MAS_WARN_ON(&mas, (end < mt_min_slot_count(mas.node)) &&
(mas.max != ULONG_MAX))) {
- pr_err("Invalid size %u of %p\n", end, mas_mn(&mas));
+ pr_err("Invalid size %u of %px\n", end, mas_mn(&mas));
}

mas_validate_parent_slot(&mas);
@@ -7607,7 +7607,7 @@ EXPORT_SYMBOL_GPL(mt_validate);

void mas_dump(const struct ma_state *mas)
{
- pr_err("MAS: tree=%p enode=%p ", mas->tree, mas->node);
+ pr_err("MAS: tree=%px enode=%px ", mas->tree, mas->node);
switch (mas->status) {
case ma_active:
pr_err("(ma_active)");
@@ -7671,7 +7671,7 @@ void mas_dump(const struct ma_state *mas)

pr_err("[%u/%u] index=%lx last=%lx\n", mas->offset, mas->end,
mas->index, mas->last);
- pr_err(" min=%lx max=%lx alloc=%p, depth=%u, flags=%x\n",
+ pr_err(" min=%lx max=%lx alloc=%px, depth=%u, flags=%x\n",
mas->min, mas->max, mas->alloc, mas->depth, mas->mas_flags);
if (mas->index > mas->last)
pr_err("Check index & last\n");
@@ -7680,7 +7680,7 @@ EXPORT_SYMBOL_GPL(mas_dump);

void mas_wr_dump(const struct ma_wr_state *wr_mas)
{
- pr_err("WR_MAS: node=%p r_min=%lx r_max=%lx\n",
+ pr_err("WR_MAS: node=%px r_min=%lx r_max=%lx\n",
wr_mas->node, wr_mas->r_min, wr_mas->r_max);
pr_err(" type=%u off_end=%u, node_end=%u, end_piv=%lx\n",
wr_mas->type, wr_mas->offset_end, wr_mas->mas->end,
diff --git a/mm/internal.h b/mm/internal.h
index 93083bbeeefa..cd9414b4651d 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -1443,4 +1443,19 @@ static inline void accept_page(struct page *page)
}
#endif /* CONFIG_UNACCEPTED_MEMORY */

+static inline bool check_interesting(unsigned long start, unsigned long end)
+{
+ const unsigned long interesting_start = 0x1740000;
+ /* Include off-by-one on purpose.*/
+ const unsigned long interesting_end = 0x68000000 + 1;
+
+ /* interesting_start interesting_end
+ * |--------------------------|
+ * ============================> end
+ * <============================= start
+ */
+ return end > interesting_start && /* after or overlaps... */
+ start < interesting_end; /* ...overlaps. */
+}
+
#endif /* __MM_INTERNAL_H */
diff --git a/mm/mmap.c b/mm/mmap.c
index dd4b35a25aeb..8c5af1644a9b 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1341,6 +1341,18 @@ struct vm_area_struct *expand_stack(struct mm_struct *mm, unsigned long addr)
return vma;
}

+static void ljs_dump(struct mm_struct *mm,
+ unsigned long addr, unsigned long len,
+ vm_flags_t vm_flags, bool is_unmap)
+{
+ if (!check_interesting(addr, addr + len))
+ return;
+
+ pr_err("LJS: %s mm=%p [0x%lx, 0x%lx) [vm_flags=%lu]\n",
+ is_unmap ? "munmap" : "mmap", mm, addr, addr + len,
+ vm_flags);
+}
+
/* do_munmap() - Wrapper function for non-maple tree aware do_munmap() calls.
* @mm: The mm_struct
* @start: The start address to munmap
@@ -1354,6 +1366,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len,
{
VMA_ITERATOR(vmi, mm, start);

+ ljs_dump(mm, start, len, 0, true);
+
return do_vmi_munmap(&vmi, mm, start, len, uf, false);
}

@@ -1375,11 +1389,16 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
VMA_ITERATOR(vmi, mm, addr);
VMG_STATE(vmg, mm, &vmi, addr, end, vm_flags, pgoff);

+ ljs_dump(mm, addr, len, vm_flags, false);
+
vmg.file = file;
/* Find the first overlapping VMA */
vma = vma_find(&vmi, end);
init_vma_munmap(&vms, &vmi, vma, addr, end, uf, /* unlock = */ false);
if (vma) {
+ if (check_interesting(addr, addr + len))
+ pr_err("LJS: mm=%p About to do unmaps for vms=[%lx, %lx), addr=%lx, end=%lx\n", mm, addr, addr + len, vma_iter_addr(&vmi), vma_iter_end(&vmi));
+
mt_init_flags(&mt_detach, vmi.mas.tree->ma_flags & MT_FLAGS_LOCK_MASK);
mt_on_stack(mt_detach);
mas_init(&mas_detach, &mt_detach, /* addr = */ 0);
@@ -1390,6 +1409,12 @@ unsigned long mmap_region(struct file *file, unsigned long addr,

vmg.next = vms.next;
vmg.prev = vms.prev;
+
+ if (check_interesting(addr, addr + len))
+ pr_err("LJS: prev=[%lx, %lx), next=[%lx, %lx)\n",
+ vmg.prev ? vmg.prev->vm_start : 0, vmg.prev ? vmg.prev->vm_end : 0,
+ vmg.next ? vmg.next->vm_start : 0, vmg.next ? vmg.next->vm_end : 0);
+
vma = NULL;
} else {
vmg.next = vma_iter_next_rewind(&vmi, &vmg.prev);
@@ -1413,9 +1438,43 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
vmg.flags = vm_flags;
}

+ if (check_interesting(addr, addr + len)) {
+ char *special = vm_flags & VM_SPECIAL ? "special" : "";
+ char *has_file = file ? "file-backed" : "";
+
+ pr_err("LJS: Interesting [%lx, %lx) flags=%lu, special=[%s] file=[%s] addr=%lx end=%lx\n",
+ addr, addr+len, vm_flags, special, has_file,
+ vma_iter_addr(&vmi), vma_iter_end(&vmi));
+
+ mt_validate(&mm->mm_mt);
+ pr_err("LJS: Post-validate.\n");
+ }
+
+ if (addr == 0x1b90000 && addr + len == 0x1bae000 && vm_flags == 2097264) {
+ pr_err("LJS: PRE NUCLEAR ============================>");
+
+ mt_dump(vmi.mas.tree, mt_dump_hex);
+
+ pr_err("LJS:/PRE NUCLEAR <============================");
+ }
+
vma = vma_merge_new_range(&vmg);
- if (vma)
+ if (vma) {
+ if (check_interesting(addr, addr + len)) {
+ pr_err("LJS: Merged to [%lx, %lx), addr=%lx, end=%lx\n",
+ vma->vm_start, vma->vm_end, vma_iter_addr(&vmi),
+ vma_iter_end(&vmi));
+
+ mt_validate(&mm->mm_mt);
+
+ pr_err("LJS: Post-validate.\n");
+ }
+
goto expanded;
+ } else if (check_interesting(addr, addr + len)) {
+ pr_err("LJS: Failed to merge [%lx, %lx), reset...\n",
+ addr, addr + len);
+ }
/*
* Determine the object being mapped and call the appropriate
* specific mapper. the address has already been validated, but
@@ -1441,6 +1500,12 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
if (error)
goto unmap_and_free_vma;

+ if (check_interesting(addr, addr + len)) {
+ pr_err("LJS: call_mmap() on [%lx, %lx) old_flags=%lu new_flags=%lu new range=[%lx, %lx) [CHANGED=%s]\n",
+ addr, end, vm_flags, vma->vm_flags, vma->vm_start, vma->vm_end,
+ vm_flags != vma->vm_flags ? "YES" : "NO");
+ }
+
if (vma_is_shared_maywrite(vma)) {
error = mapping_map_writable(file->f_mapping);
if (error)
@@ -1467,6 +1532,11 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
/* If this fails, state is reset ready for a reattempt. */
merge = vma_merge_new_range(&vmg);

+ if (check_interesting(addr, addr + len))
+ pr_err("LJS: flags changed for [%lx, %lx) from %lu to %lu %s\n",
+ vma->vm_start, vma->vm_end, vm_flags, vma->vm_flags,
+ merge ? "merged" : "");
+
if (merge) {
/*
* ->mmap() can change vma->vm_file and fput
@@ -1511,9 +1581,22 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
/* Lock the VMA since it is modified after insertion into VMA tree */
vma_start_write(vma);
vma_iter_store(&vmi, vma);
+
+ if (check_interesting(addr, addr + len))
+ pr_err("LJS: mm=%p: iter store addr=%lx, end=%lx, vma=[%lx, %lx)\n",
+ mm, vma_iter_addr(&vmi), vma_iter_end(&vmi), vma->vm_start, vma->vm_end);
+
mm->map_count++;
vma_link_file(vma);

+ if (check_interesting(addr, addr + len)) {
+ pr_err("LJS: mm=%p: About to validate [%lx, %lx) addr=%lx, end=%lx\n",
+ mm, vma->vm_start,vma->vm_end, vma_iter_addr(&vmi), vma_iter_end(&vmi));
+
+ mt_validate(&mm->mm_mt);
+ pr_err("LJS: Post-validate.\n");
+ }
+
/*
* vma_merge_new_range() calls khugepaged_enter_vma() too, the below
* call covers the non-merge case.
@@ -1530,6 +1613,14 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
perf_event_mmap(vma);

/* Unmap any existing mapping in the area */
+
+ if (check_interesting(addr, addr + len)) {
+ pr_err("LJS: mm=%p: About to validate [%lx, %lx) addr=%lx, end=%lx\n",
+ mm, vma->vm_start,vma->vm_end, vma_iter_addr(&vmi), vma_iter_end(&vmi));
+ mt_validate(&mm->mm_mt);
+ pr_err("LJS: Post-validate.\n");
+ }
+
vms_complete_munmap_vmas(&vms, &mas_detach);

vm_stat_account(mm, vm_flags, pglen);
@@ -1594,6 +1685,8 @@ static int __vm_munmap(unsigned long start, size_t len, bool unlock)
LIST_HEAD(uf);
VMA_ITERATOR(vmi, mm, start);

+ ljs_dump(mm, start, start + len, 0, true);
+
if (mmap_write_lock_killable(mm))
return -EINTR;

diff --git a/mm/vma.c b/mm/vma.c
index 4737afcb064c..729575903fb1 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -605,8 +605,15 @@ static int commit_merge(struct vma_merge_struct *vmg,
vma_adjust_trans_huge(vmg->vma, vmg->start, vmg->end, adj_start);
vma_set_range(vmg->vma, vmg->start, vmg->end, vmg->pgoff);

- if (expanded)
+ if (expanded) {
+ if (check_interesting(vmg->start, vmg->end)) {
+ pr_err("LJS: mm=%p expanding to [%lx, %lx) addr=%lx end=%lx\n",
+ vmg->mm, vmg->start, vmg->end,
+ vma_iter_addr(vmg->vmi), vma_iter_end(vmg->vmi));
+ }
+
vma_iter_store(vmg->vmi, vmg->vma);
+ }

if (adj_start) {
adjust->vm_start += adj_start;
@@ -956,6 +963,12 @@ struct vm_area_struct *vma_merge_new_range(struct vma_merge_struct *vmg)
vma_prev(vmg->vmi); /* Equivalent to going to the previous range */
}

+ if (check_interesting(start, end)) {
+ pr_err("LJS: mm=%p About to merge [%lx, %lx) to range [%lx, %lx), addr=%lx end=%lx\n",
+ vmg->mm, start, end, vmg->start, vmg->end,
+ vma_iter_addr(vmg->vmi), vma_iter_end(vmg->vmi));
+ }
+
/*
* Now try to expand adjacent VMA(s). This takes care of removing the
* following VMA if we have VMAs on both sides.
@@ -1108,8 +1121,13 @@ void vms_clean_up_area(struct vma_munmap_struct *vms,
vms_clear_ptes(vms, mas_detach, true);
mas_set(mas_detach, 0);
mas_for_each(mas_detach, vma, ULONG_MAX)
- if (vma->vm_ops && vma->vm_ops->close)
+ if (vma->vm_ops && vma->vm_ops->close) {
+ if (check_interesting(vma->vm_start, vma->vm_end))
+ pr_err("LJS: mm=%p Closing [%lx, %lx)\n",
+ vma->vm_mm, vma->vm_start, vma->vm_end);
+
vma->vm_ops->close(vma);
+ }
vms->closed_vm_ops = true;
}

@@ -1179,6 +1197,10 @@ int vms_gather_munmap_vmas(struct vma_munmap_struct *vms,
struct vm_area_struct *next = NULL;
int error;

+ if (check_interesting(vms->vma->vm_start, vms->vma->vm_end))
+ pr_err("LJS2 vms->start=%lx, vms->vma->vm_start=%lx\n",
+ vms->start, vms->vma->vm_start);
+
/*
* If we need to split any vma, do it now to save pain later.
* Does it split the first one?
@@ -1202,6 +1224,11 @@ int vms_gather_munmap_vmas(struct vma_munmap_struct *vms,
goto start_split_failed;
}

+ if (check_interesting(vms->vma->vm_start, vms->vma->vm_end))
+ pr_err("LJS: mm=%p vms=[%lx, %lx) split START of [%lx, %lx)\n",
+ vms->vma->vm_mm, vms->start, vms->end,
+ vms->vma->vm_start, vms->vma->vm_end);
+
error = __split_vma(vms->vmi, vms->vma, vms->start, 1);
if (error)
goto start_split_failed;
@@ -1217,12 +1244,24 @@ int vms_gather_munmap_vmas(struct vma_munmap_struct *vms,
for_each_vma_range(*(vms->vmi), next, vms->end) {
long nrpages;

+ if (check_interesting(vms->vma->vm_start, vms->vma->vm_end))
+ pr_err("LJS: mm=%p vms=[%lx, %lx) UNMAP [%lx, %lx) file=[%s]\n",
+ vms->vma->vm_mm, vms->start, vms->end,
+ next->vm_start, next->vm_end,
+ vms->vma->vm_file ? "file-backed" : "");
+
if (!can_modify_vma(next)) {
error = -EPERM;
goto modify_vma_failed;
}
/* Does it split the end? */
if (next->vm_end > vms->end) {
+
+ if (check_interesting(next->vm_start, next->vm_end))
+ pr_err("LJS: mm=%p vms=[%lx, %lx) split END of [%lx, %lx)\n",
+ next->vm_mm, vms->start, vms->end,
+ next->vm_start, next->vm_end);
+
error = __split_vma(vms->vmi, next, vms->end, 0);
if (error)
goto end_split_failed;
@@ -1295,9 +1334,15 @@ int vms_gather_munmap_vmas(struct vma_munmap_struct *vms,
}
#endif

- while (vma_iter_addr(vms->vmi) > vms->start)
+ while (vma_iter_addr(vms->vmi) > vms->start) {
vma_iter_prev_range(vms->vmi);

+ if (check_interesting(vms->vma->vm_start, vms->vma->vm_end))
+ pr_err("LJS3: addr=%lx, end=%lx, vms->start=%lx\n",
+ vma_iter_addr(vms->vmi),
+ vma_iter_end(vms->vmi), vms->start);
+ }
+
vms->clear_ptes = true;
return 0;

--
2.46.2