mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 1/1] selftests/proc: use RSS in /proc/pid/smaps_rollup tearing tests
@ 2026-11-01 15:45 Suren Baghdasaryan
  2026-11-01 19:01 ` Andrew Morton
  2026-11-02 13:26 ` Pedro Falcato
  0 siblings, 2 replies; 10+ messages in thread
From: Suren Baghdasaryan @ 2026-11-01 15:45 UTC (permalink / raw)
  To: akpm
  Cc: david, ljs, jannh, liam, willy, paulmck, pfalcato, usama.arif,
	vbabka, linux-fsdevel, yi1.lai, oe-lkp, lkp, linux-kernel,
	Suren Baghdasaryan

Pss metrics can be affected by map count even if VMA tree stays unchanged,
therefore tests checking VMA tree integrity can't use them. Use Rss instead
and pre-populate the VMAs so that Rss changes if a VMA gets skipped or
double-counted.

To ensure all test VMAs are populated with anonymous pages, remain
mergeable across VMA operations, and do not have their Rss changed by
memory reclaim:
- Toggle PROT_EXEC instead of PROT_WRITE between adjacent test VMAs so
  all test VMAs remain writable and MAP_POPULATE faults in anonymous pages
  (rather than the shared zero page, which is not accounted in Rss).
- Use mprotect() instead of mmap(..., MAP_FIXED) in split_vma() and
  merge_vma() so the first page of the split VMA stays resident.
  mprotect(..., PROT_NONE) splits the VMA without unmapping the first page
  (pte_present() remains true for PAGE_NONE PTEs), and
  mprotect(..., self->mod_info->prot) merges it back. Both parts of the
  split VMA retain their non-zero Rss.
- Lock all present pages in the child with mlockall(MCL_CURRENT |
  MCL_FUTURE | MCL_ONFAULT) so memory pressure cannot reclaim pages and
  alter Rss during the test.
- In remap_vma(), unlock next_addr before mremap(..., MREMAP_DONTUNMAP)
  so next_addr is not split, use mmap(..., MAP_FIXED) in patch_vma() to
  merge the middle VMA back into addr, and exclude smaps_rollup tests
  from test_maps_tearing_from_remap since remapping moves and unmaps the
  page from next_addr.

Fixes: ca5480fb53fa ("selftests/proc: add /proc/pid/smaps_rollup tearing tests")
Reported-by: kernel test robot <yi1.lai@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202610271934.fd287c3f-lkp@intel.com
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
---
Changes from v1 [1]:
- fixed the way the odd VMAs are populated to avoid mapping zero pages
- used mprotect for splitting/merging VMAs to prevent split_vma() from
  unmapping and freeing the first page
- mlock all areas to keep Rss unchanged under memory pressure,
  per Pedro Falcato
- exclude smaps_rollup tests from test_maps_tearing_from_remap because
  remapping a populated VMA affects Rss metric

[1] https://lore.kernel.org/all/20261028051312.1505295-1-surenb@google.com/

 tools/testing/selftests/proc/proc-maps-race.c | 53 ++++++++++---------
 1 file changed, 27 insertions(+), 26 deletions(-)

diff --git a/tools/testing/selftests/proc/proc-maps-race.c b/tools/testing/selftests/proc/proc-maps-race.c
index bf4c5073f6fc..6025aea68190 100644
--- a/tools/testing/selftests/proc/proc-maps-race.c
+++ b/tools/testing/selftests/proc/proc-maps-race.c
@@ -528,13 +528,10 @@ static bool compare_smaps_rollup(FIXTURE_DATA(proc_maps_race) *self,
 		struct smaps_rollup_stats *actual)
 {
 	/*
-	 * Clean/dirty metrics might change but Pss-related ones
-	 * should stay constant.
+	 * Clean/dirty metrics might change. Pss depends on map count and might
+	 * change as well. Rss should stay constant.
 	 */
-	if (cmp_smaps_rollup_stat(expected, actual, Pss) &&
-	    cmp_smaps_rollup_stat(expected, actual, Pss_Anon) &&
-	    cmp_smaps_rollup_stat(expected, actual, Pss_File) &&
-	    cmp_smaps_rollup_stat(expected, actual, Pss_Shmem))
+	if (cmp_smaps_rollup_stat(expected, actual, Rss))
 		return true;
 
 	print_smaps_rollup_stats("Expected stats:", self, expected);
@@ -637,14 +634,13 @@ static bool query_addr_at(int maps_fd, void *addr,
 static inline bool split_vma(FIXTURE_DATA(proc_maps_race) *self)
 {
 	/* PROT_NONE differs from both readable neighbors. */
-	return mmap(self->mod_info->addr, self->page_size, PROT_NONE,
-		    MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != MAP_FAILED;
+	return mprotect(self->mod_info->addr, self->page_size, PROT_NONE) == 0;
 }
 
 static inline bool merge_vma(FIXTURE_DATA(proc_maps_race) *self)
 {
-	return mmap(self->mod_info->addr, self->page_size, self->mod_info->prot,
-		    MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != MAP_FAILED;
+	return mprotect(self->mod_info->addr, self->page_size,
+			self->mod_info->prot) == 0;
 }
 
 static inline bool check_split_result(struct line_content *mod_last_line,
@@ -681,6 +677,12 @@ static inline bool check_shrink_result(struct line_content *mod_last_line,
 
 static inline bool remap_vma(FIXTURE_DATA(proc_maps_race) *self)
 {
+	/*
+	 * Unlock next_addr so MREMAP_DONTUNMAP does not split it.
+	 */
+	if (munlock(self->mod_info->next_addr, self->page_size * 3) != 0)
+		return false;
+
 	/*
 	 * Remap the last page of the next vma into the middle of the vma.
 	 * This splits the current vma and the first and middle parts (the
@@ -694,8 +696,9 @@ static inline bool remap_vma(FIXTURE_DATA(proc_maps_race) *self)
 
 static inline bool patch_vma(FIXTURE_DATA(proc_maps_race) *self)
 {
-	return mprotect(self->mod_info->addr + self->page_size, self->page_size,
-			self->mod_info->prot) == 0;
+	return mmap(self->mod_info->addr + self->page_size, self->page_size,
+		    self->mod_info->prot,
+		    MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != MAP_FAILED;
 }
 
 static inline bool check_remap_result(struct line_content *mod_last_line,
@@ -759,11 +762,17 @@ FIXTURE_SETUP(proc_maps_race)
 
 		for (i = 0; i < mod_info->vma_count; i++) {
 			mod_info->child_mapped_addr[i] = mmap(NULL, self->page_size * 3, prot,
-					MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+					MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
 			ASSERT_NE(mod_info->child_mapped_addr[i], MAP_FAILED);
 			/* change protection in adjacent maps to prevent merging */
-			prot ^= PROT_WRITE;
+			prot ^= PROT_EXEC;
 		}
+		/*
+		 * Lock all present pages in memory so memory reclaim cannot
+		 * change RSS during the test, and use MCL_ONFAULT so
+		 * mremap() expansion does not populate new pages.
+		 */
+		ASSERT_EQ(mlockall(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT), 0);
 		signal_state(mod_info, CHILD_READY);
 		wait_for_state(mod_info, PARENT_READY);
 		while (true) {
@@ -833,10 +842,10 @@ FIXTURE_SETUP(proc_maps_race)
 	for (int i = 0; i < mod_info->vma_count; i++) {
 		if (mod_info->child_mapped_addr[i] == (void *)self->last_line.start_addr) {
 			mod_info->addr = mod_info->child_mapped_addr[i];
-			mod_info->prot = PROT_READ;
-			/* Even VMAs have write permission */
-			if ((i % 2) == 0)
-				mod_info->prot |= PROT_WRITE;
+			mod_info->prot = PROT_READ | PROT_WRITE;
+			/* Odd VMAs have exec permission */
+			if ((i % 2) != 0)
+				mod_info->prot |= PROT_EXEC;
 		} else if (mod_info->child_mapped_addr[i] == (void *)self->first_line.start_addr) {
 			mod_info->next_addr = mod_info->child_mapped_addr[i];
 		}
@@ -1066,7 +1075,6 @@ TEST_F(proc_maps_race, test_maps_tearing_from_remap)
 	struct line_content remapped_first_line;
 	struct line_content restored_last_line;
 	struct line_content restored_first_line;
-	struct smaps_rollup_stats orig_stats;
 
 	wait_for_state(mod_info, SETUP_READY);
 
@@ -1080,8 +1088,6 @@ TEST_F(proc_maps_race, test_maps_tearing_from_remap)
 	report_test_start("Tearing from remap", self->verbose);
 	ASSERT_TRUE(capture_mod_pattern(self, &remapped_last_line, &remapped_first_line,
 					&restored_last_line, &restored_first_line));
-	if (self->maps_file == SMAPS)
-		ASSERT_TRUE(parse_smaps_rollup(self, &orig_stats));
 
 	/* Now start concurrent modifications for self->duration_sec */
 	signal_state(mod_info, TEST_READY);
@@ -1134,11 +1140,6 @@ TEST_F(proc_maps_race, test_maps_tearing_from_remap)
 				     vma_end - vma_start == self->page_size * 3) ||
 				    (vma_start == self->last_line.start_addr + self->page_size &&
 				     vma_end - vma_start == self->page_size));
-		} else {
-			struct smaps_rollup_stats stats;
-
-			ASSERT_TRUE(parse_smaps_rollup(self, &stats));
-			ASSERT_TRUE(compare_smaps_rollup(self, &orig_stats, &stats));
 		}
 		clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts);
 		end_test_iteration(&end_ts, self->verbose);

base-commit: b61fa14ce6bcbba2cb9a96feea31b760226d6b43
-- 
2.56.0.317.g454f8302e1-goog


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/1] selftests/proc: use RSS in /proc/pid/smaps_rollup tearing tests
  2026-11-01 15:45 [PATCH v2 1/1] selftests/proc: use RSS in /proc/pid/smaps_rollup tearing tests Suren Baghdasaryan
@ 2026-11-01 19:01 ` Andrew Morton
  2026-11-02 13:08   ` Pedro Falcato
  2026-11-02 15:43   ` Suren Baghdasaryan
  2026-11-02 13:26 ` Pedro Falcato
  1 sibling, 2 replies; 10+ messages in thread
From: Andrew Morton @ 2026-11-01 19:01 UTC (permalink / raw)
  To: Suren Baghdasaryan
  Cc: david, ljs, jannh, liam, willy, paulmck, pfalcato, usama.arif,
	vbabka, linux-fsdevel, yi1.lai, oe-lkp, lkp, linux-kernel

On Sun,  1 Nov 2026 07:45:03 -0800 Suren Baghdasaryan <surenb@google.com> wrote:

> Pss metrics can be affected by map count even if VMA tree stays unchanged,
> therefore tests checking VMA tree integrity can't use them. Use Rss instead
> and pre-populate the VMAs so that Rss changes if a VMA gets skipped or
> double-counted.
> 
> To ensure all test VMAs are populated with anonymous pages, remain
> mergeable across VMA operations, and do not have their Rss changed by
> memory reclaim:
> - Toggle PROT_EXEC instead of PROT_WRITE between adjacent test VMAs so
>   all test VMAs remain writable and MAP_POPULATE faults in anonymous pages
>   (rather than the shared zero page, which is not accounted in Rss).
> - Use mprotect() instead of mmap(..., MAP_FIXED) in split_vma() and
>   merge_vma() so the first page of the split VMA stays resident.
>   mprotect(..., PROT_NONE) splits the VMA without unmapping the first page
>   (pte_present() remains true for PAGE_NONE PTEs), and
>   mprotect(..., self->mod_info->prot) merges it back. Both parts of the
>   split VMA retain their non-zero Rss.
> - Lock all present pages in the child with mlockall(MCL_CURRENT |
>   MCL_FUTURE | MCL_ONFAULT) so memory pressure cannot reclaim pages and
>   alter Rss during the test.
> - In remap_vma(), unlock next_addr before mremap(..., MREMAP_DONTUNMAP)
>   so next_addr is not split, use mmap(..., MAP_FIXED) in patch_vma() to
>   merge the middle VMA back into addr, and exclude smaps_rollup tests
>   from test_maps_tearing_from_remap since remapping moves and unmaps the
>   page from next_addr.

Thanks.  This is proving tricky.

My evolving reviewbot still isn't happy:

: This fixes the v1 RSS issues, but two things remain.
: 
: Alternating PROT_EXEC breaks with READ_IMPLIES_EXEC: both mappings
: become RWX and can merge. A syscall test produced two VMAs instead
: of 16. Could we populate everything writable, then mprotect the odd
: mappings read-only? That preserved all 16 VMAs and avoids zero pages.
: 
: Also, MCL_ONFAULT doesn't bypass RLIMIT_MEMLOCK. If mlockall() fails,
: the child asserts before CHILD_READY and the parent waits until
: timeout. Please arrange a coordinated skip for insufficient allowance.
: 
: The patched userspace test passed all six cases on an existing
: x86-64 6.18.57 kernel, with a PID-namespace adjustment. That kernel
: predates ca5480fb53fa, so this checks selftest behavior, not the
: intended kernel's procfs changes. Separate syscall tests on that
: kernel confirmed the EXEC-merging and memlock failure cases.

I said "no, do it yourself" and it came up with the below.




From: Andrew Morton <akpm@linux-foundation.org>
Subject: selftests/proc: handle personality and memlock constraints
Date: Sun, 01 Nov 2026 10:55:37 -0800

Alternating PROT_EXEC does not keep the test mappings distinct when
READ_IMPLIES_EXEC is set: both protection combinations become RWX and
adjacent mappings can merge, breaking the fixture's layout assumptions.

Populate each mapping writable, then make odd mappings read-only.  This
retains anonymous pages accounted in RSS while keeping adjacent VMAs
distinct regardless of READ_IMPLIES_EXEC.  Restore the corresponding
WRITE-based protection selection in the parent.

Restore the whole three-page destination after remapping, rather than
replacing only its middle page and relying on the remaining anonymous VMAs
to merge.  The remap test no longer compares RSS.

mlockall(MCL_CURRENT) checks the whole virtual size against the locked
memory allowance even with MCL_ONFAULT.  An insufficient allowance makes
the child exit before CHILD_READY, leaving the parent waiting until the
test times out.

Pass the locking error through the existing shared state and signal
CHILD_READY on failure.  The parent reaps the child and releases the
shared state before skipping resource or permission failures.  Check this
status before opening the child's proc files, as it may already have
exited.  Unexpected locking errors remain test failures.

Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Jann Horn <jannh@google.com>
Cc: kernel test robot <yi1.lai@intel.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Paul E. McKenney <paulmck@kernel.org>
Cc: Pedro Falcato <pfalcato@suse.de>
Cc: Usama Arif <usama.arif@linux.dev>
Cc: Vlastimil Babka <vbabka@kernel.org>
---
On top of Suren's v2 "selftests/proc: use RSS in
/proc/pid/smaps_rollup tearing tests".

Tested the userspace test on an existing x86-64 Linux 6.18.57 kernel,
using a separate PID-namespace adaptation which is not in this patch:
- All six cases passed normally and with READ_IMPLIES_EXEC enabled,
  using DURATION=1.
- All six cases skipped promptly with RLIMIT_MEMLOCK set to 64KiB or
  zero, exercising ENOMEM and EPERM respectively.
This does not validate the intended kernel's procfs changes.

 tools/testing/selftests/proc/proc-maps-race.c |   49 +++++++++++-----
 1 file changed, 36 insertions(+), 13 deletions(-)

--- a/tools/testing/selftests/proc/proc-maps-race.c~proc-maps-race-followup
+++ a/tools/testing/selftests/proc/proc-maps-race.c
@@ -174,6 +174,7 @@ typedef bool (*vma_mod_result_check_op)(
 					struct line_content *restored_first_line);
 
 struct vma_modifier_info {
+	int mlock_error;
 	int vma_count;
 	void *addr;
 	int prot;
@@ -696,7 +697,8 @@ static inline bool remap_vma(FIXTURE_DAT
 
 static inline bool patch_vma(FIXTURE_DATA(proc_maps_race) *self)
 {
-	return mmap(self->mod_info->addr + self->page_size, self->page_size,
+	/* Replace all three pieces without relying on anon_vma merging. */
+	return mmap(self->mod_info->addr, self->page_size * 3,
 		    self->mod_info->prot,
 		    MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != MAP_FAILED;
 }
@@ -757,22 +759,31 @@ FIXTURE_SETUP(proc_maps_race)
 	self->pid = fork();
 	if (!self->pid) {
 		/* Child process modifying the address space */
-		int prot = PROT_READ | PROT_WRITE;
 		int i;
 
 		for (i = 0; i < mod_info->vma_count; i++) {
-			mod_info->child_mapped_addr[i] = mmap(NULL, self->page_size * 3, prot,
+			mod_info->child_mapped_addr[i] = mmap(NULL, self->page_size * 3,
+					PROT_READ | PROT_WRITE,
 					MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
 			ASSERT_NE(mod_info->child_mapped_addr[i], MAP_FAILED);
-			/* change protection in adjacent maps to prevent merging */
-			prot ^= PROT_EXEC;
+			/*
+			 * Populate writable to get anonymous pages, then alternate
+			 * write permission even with READ_IMPLIES_EXEC enabled.
+			 */
+			if (i % 2)
+				ASSERT_EQ(mprotect(mod_info->child_mapped_addr[i],
+						   self->page_size * 3, PROT_READ), 0);
 		}
 		/*
 		 * Lock all present pages in memory so memory reclaim cannot
 		 * change RSS during the test, and use MCL_ONFAULT so
 		 * mremap() expansion does not populate new pages.
 		 */
-		ASSERT_EQ(mlockall(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT), 0);
+		if (mlockall(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT)) {
+			mod_info->mlock_error = errno;
+			signal_state(mod_info, CHILD_READY);
+			_exit(0);
+		}
 		signal_state(mod_info, CHILD_READY);
 		wait_for_state(mod_info, PARENT_READY);
 		while (true) {
@@ -799,6 +810,21 @@ FIXTURE_SETUP(proc_maps_race)
 		exit(0);
 	}
 
+	/* Check setup before opening proc files: the child may have exited. */
+	wait_for_state(mod_info, CHILD_READY);
+	if (mod_info->mlock_error) {
+		int error = mod_info->mlock_error;
+		int status;
+
+		ASSERT_EQ(waitpid(self->pid, &status, 0), self->pid);
+		pthread_cond_destroy(&mod_info->sync_cond);
+		pthread_mutex_destroy(&mod_info->sync_lock);
+		munmap(mod_info, self->shared_mem_size);
+		if (error == ENOMEM || error == EPERM || error == EAGAIN)
+			SKIP(return, "Cannot lock test mappings: %s", strerror(error));
+		ASSERT_EQ(error, 0);
+	}
+
 	switch (self->maps_file) {
 	case MAPS:
 		sprintf(fname, "/proc/%d/maps", self->pid);
@@ -815,9 +841,6 @@ FIXTURE_SETUP(proc_maps_race)
 	self->maps_fd = open(fname, O_RDONLY);
 	ASSERT_NE(self->maps_fd, -1);
 
-	/* Wait for the child to map the VMAs */
-	wait_for_state(mod_info, CHILD_READY);
-
 	/* Read first two pages */
 	self->page1.data = malloc(self->page_size);
 	ASSERT_NE(self->page1.data, NULL);
@@ -842,10 +865,10 @@ FIXTURE_SETUP(proc_maps_race)
 	for (int i = 0; i < mod_info->vma_count; i++) {
 		if (mod_info->child_mapped_addr[i] == (void *)self->last_line.start_addr) {
 			mod_info->addr = mod_info->child_mapped_addr[i];
-			mod_info->prot = PROT_READ | PROT_WRITE;
-			/* Odd VMAs have exec permission */
-			if ((i % 2) != 0)
-				mod_info->prot |= PROT_EXEC;
+			mod_info->prot = PROT_READ;
+			/* Even VMAs have write permission. */
+			if ((i % 2) == 0)
+				mod_info->prot |= PROT_WRITE;
 		} else if (mod_info->child_mapped_addr[i] == (void *)self->first_line.start_addr) {
 			mod_info->next_addr = mod_info->child_mapped_addr[i];
 		}
_


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/1] selftests/proc: use RSS in /proc/pid/smaps_rollup tearing tests
  2026-11-01 19:01 ` Andrew Morton
@ 2026-11-02 13:08   ` Pedro Falcato
  2026-11-02 15:31     ` Suren Baghdasaryan
  2026-11-02 15:43   ` Suren Baghdasaryan
  1 sibling, 1 reply; 10+ messages in thread
From: Pedro Falcato @ 2026-11-02 13:08 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Suren Baghdasaryan, david, ljs, jannh, liam, willy, paulmck,
	usama.arif, vbabka, linux-fsdevel, yi1.lai, oe-lkp, lkp,
	linux-kernel

On Sun, Nov 01, 2026 at 11:01:00AM -0800, Andrew Morton wrote:
> On Sun,  1 Nov 2026 07:45:03 -0800 Suren Baghdasaryan <surenb@google.com> wrote:
> 
> > Pss metrics can be affected by map count even if VMA tree stays unchanged,
> > therefore tests checking VMA tree integrity can't use them. Use Rss instead
> > and pre-populate the VMAs so that Rss changes if a VMA gets skipped or
> > double-counted.
> > 
> > To ensure all test VMAs are populated with anonymous pages, remain
> > mergeable across VMA operations, and do not have their Rss changed by
> > memory reclaim:
> > - Toggle PROT_EXEC instead of PROT_WRITE between adjacent test VMAs so
> >   all test VMAs remain writable and MAP_POPULATE faults in anonymous pages
> >   (rather than the shared zero page, which is not accounted in Rss).
> > - Use mprotect() instead of mmap(..., MAP_FIXED) in split_vma() and
> >   merge_vma() so the first page of the split VMA stays resident.
> >   mprotect(..., PROT_NONE) splits the VMA without unmapping the first page
> >   (pte_present() remains true for PAGE_NONE PTEs), and
> >   mprotect(..., self->mod_info->prot) merges it back. Both parts of the
> >   split VMA retain their non-zero Rss.
> > - Lock all present pages in the child with mlockall(MCL_CURRENT |
> >   MCL_FUTURE | MCL_ONFAULT) so memory pressure cannot reclaim pages and
> >   alter Rss during the test.
> > - In remap_vma(), unlock next_addr before mremap(..., MREMAP_DONTUNMAP)
> >   so next_addr is not split, use mmap(..., MAP_FIXED) in patch_vma() to
> >   merge the middle VMA back into addr, and exclude smaps_rollup tests
> >   from test_maps_tearing_from_remap since remapping moves and unmaps the
> >   page from next_addr.
> 
> Thanks.  This is proving tricky.
> 
> My evolving reviewbot still isn't happy:
> 
> : This fixes the v1 RSS issues, but two things remain.
> : 
> : Alternating PROT_EXEC breaks with READ_IMPLIES_EXEC: both mappings

This is nonsense btw. Not sure we'll ever support random personality()
flags being set on selftests.

-- 
Pedro

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/1] selftests/proc: use RSS in /proc/pid/smaps_rollup tearing tests
  2026-11-01 15:45 [PATCH v2 1/1] selftests/proc: use RSS in /proc/pid/smaps_rollup tearing tests Suren Baghdasaryan
  2026-11-01 19:01 ` Andrew Morton
@ 2026-11-02 13:26 ` Pedro Falcato
  2026-11-02 15:59   ` Suren Baghdasaryan
  1 sibling, 1 reply; 10+ messages in thread
From: Pedro Falcato @ 2026-11-02 13:26 UTC (permalink / raw)
  To: Suren Baghdasaryan
  Cc: akpm, david, ljs, jannh, liam, willy, paulmck, usama.arif,
	vbabka, linux-fsdevel, yi1.lai, oe-lkp, lkp, linux-kernel

On Sun, Nov 01, 2026 at 07:45:03AM -0800, Suren Baghdasaryan wrote:
> Pss metrics can be affected by map count even if VMA tree stays unchanged,
> therefore tests checking VMA tree integrity can't use them. Use Rss instead
> and pre-populate the VMAs so that Rss changes if a VMA gets skipped or
> double-counted.
> 
> To ensure all test VMAs are populated with anonymous pages, remain
> mergeable across VMA operations, and do not have their Rss changed by
> memory reclaim:
> - Toggle PROT_EXEC instead of PROT_WRITE between adjacent test VMAs so
>   all test VMAs remain writable and MAP_POPULATE faults in anonymous pages
>   (rather than the shared zero page, which is not accounted in Rss).
> - Use mprotect() instead of mmap(..., MAP_FIXED) in split_vma() and
>   merge_vma() so the first page of the split VMA stays resident.
>   mprotect(..., PROT_NONE) splits the VMA without unmapping the first page
>   (pte_present() remains true for PAGE_NONE PTEs), and
>   mprotect(..., self->mod_info->prot) merges it back. Both parts of the
>   split VMA retain their non-zero Rss.
> - Lock all present pages in the child with mlockall(MCL_CURRENT |
>   MCL_FUTURE | MCL_ONFAULT) so memory pressure cannot reclaim pages and
>   alter Rss during the test.

FWIW, I was wondering if it would remain constant in face of compaction (page
migration). It seems so, from looking at the code the migration entry should
make it count the RSS. But is it always the case? I'm not super familiar with
the migration logic.
 

-- 
Pedro

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/1] selftests/proc: use RSS in /proc/pid/smaps_rollup tearing tests
  2026-11-02 13:08   ` Pedro Falcato
@ 2026-11-02 15:31     ` Suren Baghdasaryan
  0 siblings, 0 replies; 10+ messages in thread
From: Suren Baghdasaryan @ 2026-11-02 15:31 UTC (permalink / raw)
  To: Pedro Falcato
  Cc: Andrew Morton, david, ljs, jannh, liam, willy, paulmck,
	usama.arif, vbabka, linux-fsdevel, yi1.lai, oe-lkp, lkp,
	linux-kernel

On Mon, Nov 2, 2026 at 5:08 AM Pedro Falcato <pfalcato@suse.de> wrote:
>
> On Sun, Nov 01, 2026 at 11:01:00AM -0800, Andrew Morton wrote:
> > On Sun,  1 Nov 2026 07:45:03 -0800 Suren Baghdasaryan <surenb@google.com> wrote:
> >
> > > Pss metrics can be affected by map count even if VMA tree stays unchanged,
> > > therefore tests checking VMA tree integrity can't use them. Use Rss instead
> > > and pre-populate the VMAs so that Rss changes if a VMA gets skipped or
> > > double-counted.
> > >
> > > To ensure all test VMAs are populated with anonymous pages, remain
> > > mergeable across VMA operations, and do not have their Rss changed by
> > > memory reclaim:
> > > - Toggle PROT_EXEC instead of PROT_WRITE between adjacent test VMAs so
> > >   all test VMAs remain writable and MAP_POPULATE faults in anonymous pages
> > >   (rather than the shared zero page, which is not accounted in Rss).
> > > - Use mprotect() instead of mmap(..., MAP_FIXED) in split_vma() and
> > >   merge_vma() so the first page of the split VMA stays resident.
> > >   mprotect(..., PROT_NONE) splits the VMA without unmapping the first page
> > >   (pte_present() remains true for PAGE_NONE PTEs), and
> > >   mprotect(..., self->mod_info->prot) merges it back. Both parts of the
> > >   split VMA retain their non-zero Rss.
> > > - Lock all present pages in the child with mlockall(MCL_CURRENT |
> > >   MCL_FUTURE | MCL_ONFAULT) so memory pressure cannot reclaim pages and
> > >   alter Rss during the test.
> > > - In remap_vma(), unlock next_addr before mremap(..., MREMAP_DONTUNMAP)
> > >   so next_addr is not split, use mmap(..., MAP_FIXED) in patch_vma() to
> > >   merge the middle VMA back into addr, and exclude smaps_rollup tests
> > >   from test_maps_tearing_from_remap since remapping moves and unmaps the
> > >   page from next_addr.
> >
> > Thanks.  This is proving tricky.
> >
> > My evolving reviewbot still isn't happy:
> >
> > : This fixes the v1 RSS issues, but two things remain.
> > :
> > : Alternating PROT_EXEC breaks with READ_IMPLIES_EXEC: both mappings
>
> This is nonsense btw. Not sure we'll ever support random personality()
> flags being set on selftests.

Yeah, handling different personality() cases on a selftest sounds like
a stretch. Is this case realistic and do we need to handle it?

>
> --
> Pedro

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/1] selftests/proc: use RSS in /proc/pid/smaps_rollup tearing tests
  2026-11-01 19:01 ` Andrew Morton
  2026-11-02 13:08   ` Pedro Falcato
@ 2026-11-02 15:43   ` Suren Baghdasaryan
  2026-11-02 16:01     ` Andrew Morton
  1 sibling, 1 reply; 10+ messages in thread
From: Suren Baghdasaryan @ 2026-11-02 15:43 UTC (permalink / raw)
  To: Andrew Morton
  Cc: david, ljs, jannh, liam, willy, paulmck, pfalcato, usama.arif,
	vbabka, linux-fsdevel, yi1.lai, oe-lkp, lkp, linux-kernel

On Sun, Nov 1, 2026 at 11:01 AM Andrew Morton <akpm@linux-foundation.org> wrote:
>
> On Sun,  1 Nov 2026 07:45:03 -0800 Suren Baghdasaryan <surenb@google.com> wrote:
>
> > Pss metrics can be affected by map count even if VMA tree stays unchanged,
> > therefore tests checking VMA tree integrity can't use them. Use Rss instead
> > and pre-populate the VMAs so that Rss changes if a VMA gets skipped or
> > double-counted.
> >
> > To ensure all test VMAs are populated with anonymous pages, remain
> > mergeable across VMA operations, and do not have their Rss changed by
> > memory reclaim:
> > - Toggle PROT_EXEC instead of PROT_WRITE between adjacent test VMAs so
> >   all test VMAs remain writable and MAP_POPULATE faults in anonymous pages
> >   (rather than the shared zero page, which is not accounted in Rss).
> > - Use mprotect() instead of mmap(..., MAP_FIXED) in split_vma() and
> >   merge_vma() so the first page of the split VMA stays resident.
> >   mprotect(..., PROT_NONE) splits the VMA without unmapping the first page
> >   (pte_present() remains true for PAGE_NONE PTEs), and
> >   mprotect(..., self->mod_info->prot) merges it back. Both parts of the
> >   split VMA retain their non-zero Rss.
> > - Lock all present pages in the child with mlockall(MCL_CURRENT |
> >   MCL_FUTURE | MCL_ONFAULT) so memory pressure cannot reclaim pages and
> >   alter Rss during the test.
> > - In remap_vma(), unlock next_addr before mremap(..., MREMAP_DONTUNMAP)
> >   so next_addr is not split, use mmap(..., MAP_FIXED) in patch_vma() to
> >   merge the middle VMA back into addr, and exclude smaps_rollup tests
> >   from test_maps_tearing_from_remap since remapping moves and unmaps the
> >   page from next_addr.
>
> Thanks.  This is proving tricky.
>
> My evolving reviewbot still isn't happy:
>
> : This fixes the v1 RSS issues, but two things remain.
> :
> : Alternating PROT_EXEC breaks with READ_IMPLIES_EXEC: both mappings
> : become RWX and can merge. A syscall test produced two VMAs instead
> : of 16. Could we populate everything writable, then mprotect the odd
> : mappings read-only? That preserved all 16 VMAs and avoids zero pages.
> :
> : Also, MCL_ONFAULT doesn't bypass RLIMIT_MEMLOCK. If mlockall() fails,
> : the child asserts before CHILD_READY and the parent waits until
> : timeout. Please arrange a coordinated skip for insufficient allowance.

Good point. That part of your fix looks good to me.

> :
> : The patched userspace test passed all six cases on an existing
> : x86-64 6.18.57 kernel, with a PID-namespace adjustment. That kernel
> : predates ca5480fb53fa, so this checks selftest behavior, not the
> : intended kernel's procfs changes. Separate syscall tests on that
> : kernel confirmed the EXEC-merging and memlock failure cases.

I'm guessing your bot was using personality() to make the tests fail.
Again, I'm not sure we should handle such use case. Should we?

>
> I said "no, do it yourself" and it came up with the below.
>
>
>
>
> From: Andrew Morton <akpm@linux-foundation.org>
> Subject: selftests/proc: handle personality and memlock constraints
> Date: Sun, 01 Nov 2026 10:55:37 -0800
>
> Alternating PROT_EXEC does not keep the test mappings distinct when
> READ_IMPLIES_EXEC is set: both protection combinations become RWX and
> adjacent mappings can merge, breaking the fixture's layout assumptions.
>
> Populate each mapping writable, then make odd mappings read-only.  This
> retains anonymous pages accounted in RSS while keeping adjacent VMAs
> distinct regardless of READ_IMPLIES_EXEC.  Restore the corresponding
> WRITE-based protection selection in the parent.
>
> Restore the whole three-page destination after remapping, rather than
> replacing only its middle page and relying on the remaining anonymous VMAs
> to merge.  The remap test no longer compares RSS.
>
> mlockall(MCL_CURRENT) checks the whole virtual size against the locked
> memory allowance even with MCL_ONFAULT.  An insufficient allowance makes
> the child exit before CHILD_READY, leaving the parent waiting until the
> test times out.
>
> Pass the locking error through the existing shared state and signal
> CHILD_READY on failure.  The parent reaps the child and releases the
> shared state before skipping resource or permission failures.  Check this
> status before opening the child's proc files, as it may already have
> exited.  Unexpected locking errors remain test failures.
>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Cc: Suren Baghdasaryan <surenb@google.com>
> Cc: David Hildenbrand <david@kernel.org>
> Cc: Jann Horn <jannh@google.com>
> Cc: kernel test robot <yi1.lai@intel.com>
> Cc: Liam R. Howlett <liam@infradead.org>
> Cc: Lorenzo Stoakes <ljs@kernel.org>
> Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
> Cc: Paul E. McKenney <paulmck@kernel.org>
> Cc: Pedro Falcato <pfalcato@suse.de>
> Cc: Usama Arif <usama.arif@linux.dev>
> Cc: Vlastimil Babka <vbabka@kernel.org>
> ---
> On top of Suren's v2 "selftests/proc: use RSS in
> /proc/pid/smaps_rollup tearing tests".
>
> Tested the userspace test on an existing x86-64 Linux 6.18.57 kernel,
> using a separate PID-namespace adaptation which is not in this patch:
> - All six cases passed normally and with READ_IMPLIES_EXEC enabled,
>   using DURATION=1.
> - All six cases skipped promptly with RLIMIT_MEMLOCK set to 64KiB or
>   zero, exercising ENOMEM and EPERM respectively.
> This does not validate the intended kernel's procfs changes.
>
>  tools/testing/selftests/proc/proc-maps-race.c |   49 +++++++++++-----
>  1 file changed, 36 insertions(+), 13 deletions(-)
>
> --- a/tools/testing/selftests/proc/proc-maps-race.c~proc-maps-race-followup
> +++ a/tools/testing/selftests/proc/proc-maps-race.c
> @@ -174,6 +174,7 @@ typedef bool (*vma_mod_result_check_op)(
>                                         struct line_content *restored_first_line);
>
>  struct vma_modifier_info {
> +       int mlock_error;
>         int vma_count;
>         void *addr;
>         int prot;
> @@ -696,7 +697,8 @@ static inline bool remap_vma(FIXTURE_DAT
>
>  static inline bool patch_vma(FIXTURE_DATA(proc_maps_race) *self)
>  {
> -       return mmap(self->mod_info->addr + self->page_size, self->page_size,
> +       /* Replace all three pieces without relying on anon_vma merging. */
> +       return mmap(self->mod_info->addr, self->page_size * 3,
>                     self->mod_info->prot,
>                     MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != MAP_FAILED;
>  }
> @@ -757,22 +759,31 @@ FIXTURE_SETUP(proc_maps_race)
>         self->pid = fork();
>         if (!self->pid) {
>                 /* Child process modifying the address space */
> -               int prot = PROT_READ | PROT_WRITE;
>                 int i;
>
>                 for (i = 0; i < mod_info->vma_count; i++) {
> -                       mod_info->child_mapped_addr[i] = mmap(NULL, self->page_size * 3, prot,
> +                       mod_info->child_mapped_addr[i] = mmap(NULL, self->page_size * 3,
> +                                       PROT_READ | PROT_WRITE,
>                                         MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
>                         ASSERT_NE(mod_info->child_mapped_addr[i], MAP_FAILED);
> -                       /* change protection in adjacent maps to prevent merging */
> -                       prot ^= PROT_EXEC;
> +                       /*
> +                        * Populate writable to get anonymous pages, then alternate
> +                        * write permission even with READ_IMPLIES_EXEC enabled.
> +                        */
> +                       if (i % 2)
> +                               ASSERT_EQ(mprotect(mod_info->child_mapped_addr[i],
> +                                                  self->page_size * 3, PROT_READ), 0);
>                 }
>                 /*
>                  * Lock all present pages in memory so memory reclaim cannot
>                  * change RSS during the test, and use MCL_ONFAULT so
>                  * mremap() expansion does not populate new pages.
>                  */
> -               ASSERT_EQ(mlockall(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT), 0);
> +               if (mlockall(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT)) {
> +                       mod_info->mlock_error = errno;
> +                       signal_state(mod_info, CHILD_READY);
> +                       _exit(0);
> +               }
>                 signal_state(mod_info, CHILD_READY);
>                 wait_for_state(mod_info, PARENT_READY);
>                 while (true) {
> @@ -799,6 +810,21 @@ FIXTURE_SETUP(proc_maps_race)
>                 exit(0);
>         }
>
> +       /* Check setup before opening proc files: the child may have exited. */
> +       wait_for_state(mod_info, CHILD_READY);
> +       if (mod_info->mlock_error) {
> +               int error = mod_info->mlock_error;
> +               int status;
> +
> +               ASSERT_EQ(waitpid(self->pid, &status, 0), self->pid);
> +               pthread_cond_destroy(&mod_info->sync_cond);
> +               pthread_mutex_destroy(&mod_info->sync_lock);
> +               munmap(mod_info, self->shared_mem_size);
> +               if (error == ENOMEM || error == EPERM || error == EAGAIN)
> +                       SKIP(return, "Cannot lock test mappings: %s", strerror(error));
> +               ASSERT_EQ(error, 0);
> +       }
> +
>         switch (self->maps_file) {
>         case MAPS:
>                 sprintf(fname, "/proc/%d/maps", self->pid);
> @@ -815,9 +841,6 @@ FIXTURE_SETUP(proc_maps_race)
>         self->maps_fd = open(fname, O_RDONLY);
>         ASSERT_NE(self->maps_fd, -1);
>
> -       /* Wait for the child to map the VMAs */
> -       wait_for_state(mod_info, CHILD_READY);
> -
>         /* Read first two pages */
>         self->page1.data = malloc(self->page_size);
>         ASSERT_NE(self->page1.data, NULL);
> @@ -842,10 +865,10 @@ FIXTURE_SETUP(proc_maps_race)
>         for (int i = 0; i < mod_info->vma_count; i++) {
>                 if (mod_info->child_mapped_addr[i] == (void *)self->last_line.start_addr) {
>                         mod_info->addr = mod_info->child_mapped_addr[i];
> -                       mod_info->prot = PROT_READ | PROT_WRITE;
> -                       /* Odd VMAs have exec permission */
> -                       if ((i % 2) != 0)
> -                               mod_info->prot |= PROT_EXEC;
> +                       mod_info->prot = PROT_READ;
> +                       /* Even VMAs have write permission. */
> +                       if ((i % 2) == 0)
> +                               mod_info->prot |= PROT_WRITE;
>                 } else if (mod_info->child_mapped_addr[i] == (void *)self->first_line.start_addr) {
>                         mod_info->next_addr = mod_info->child_mapped_addr[i];
>                 }
> _
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/1] selftests/proc: use RSS in /proc/pid/smaps_rollup tearing tests
  2026-11-02 13:26 ` Pedro Falcato
@ 2026-11-02 15:59   ` Suren Baghdasaryan
  0 siblings, 0 replies; 10+ messages in thread
From: Suren Baghdasaryan @ 2026-11-02 15:59 UTC (permalink / raw)
  To: Pedro Falcato
  Cc: akpm, david, ljs, jannh, liam, willy, paulmck, usama.arif,
	vbabka, linux-fsdevel, yi1.lai, oe-lkp, lkp, linux-kernel

On Mon, Nov 2, 2026 at 5:26 AM Pedro Falcato <pfalcato@suse.de> wrote:
>
> On Sun, Nov 01, 2026 at 07:45:03AM -0800, Suren Baghdasaryan wrote:
> > Pss metrics can be affected by map count even if VMA tree stays unchanged,
> > therefore tests checking VMA tree integrity can't use them. Use Rss instead
> > and pre-populate the VMAs so that Rss changes if a VMA gets skipped or
> > double-counted.
> >
> > To ensure all test VMAs are populated with anonymous pages, remain
> > mergeable across VMA operations, and do not have their Rss changed by
> > memory reclaim:
> > - Toggle PROT_EXEC instead of PROT_WRITE between adjacent test VMAs so
> >   all test VMAs remain writable and MAP_POPULATE faults in anonymous pages
> >   (rather than the shared zero page, which is not accounted in Rss).
> > - Use mprotect() instead of mmap(..., MAP_FIXED) in split_vma() and
> >   merge_vma() so the first page of the split VMA stays resident.
> >   mprotect(..., PROT_NONE) splits the VMA without unmapping the first page
> >   (pte_present() remains true for PAGE_NONE PTEs), and
> >   mprotect(..., self->mod_info->prot) merges it back. Both parts of the
> >   split VMA retain their non-zero Rss.
> > - Lock all present pages in the child with mlockall(MCL_CURRENT |
> >   MCL_FUTURE | MCL_ONFAULT) so memory pressure cannot reclaim pages and
> >   alter Rss during the test.
>
> FWIW, I was wondering if it would remain constant in face of compaction (page
> migration). It seems so, from looking at the code the migration entry should
> make it count the RSS. But is it always the case? I'm not super familiar with
> the migration logic.

I'll double-check, but it seems logical to me that page migration
should not affect RSS.

>
> --
> Pedro

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/1] selftests/proc: use RSS in /proc/pid/smaps_rollup tearing tests
  2026-11-02 15:43   ` Suren Baghdasaryan
@ 2026-11-02 16:01     ` Andrew Morton
  2026-11-02 16:11       ` Suren Baghdasaryan
  0 siblings, 1 reply; 10+ messages in thread
From: Andrew Morton @ 2026-11-02 16:01 UTC (permalink / raw)
  To: Suren Baghdasaryan
  Cc: david, ljs, jannh, liam, willy, paulmck, pfalcato, usama.arif,
	vbabka, linux-fsdevel, yi1.lai, oe-lkp, lkp, linux-kernel

On Mon, 2 Nov 2026 07:43:17 -0800 Suren Baghdasaryan <surenb@google.com> wrote:

> > :
> > : The patched userspace test passed all six cases on an existing
> > : x86-64 6.18.57 kernel, with a PID-namespace adjustment. That kernel
> > : predates ca5480fb53fa, so this checks selftest behavior, not the
> > : intended kernel's procfs changes. Separate syscall tests on that
> > : kernel confirmed the EXEC-merging and memlock failure cases.
> 
> I'm guessing your bot was using personality() to make the tests fail.
> Again, I'm not sure we should handle such use case. Should we?


: The concern is pre-ARMv6 CPUs, where READ_IMPLIES_EXEC is set by
: default. Nobody needs to call personality() to encounter this there.
: 
: We already addressed this in 0685630fdccb ("selftests/proc: make
: proc-maps-race work with READ_IMPLIES_EXEC"):
: 
: https://lore.kernel.org/r/20260808200312.6326-1-kmehltretter@gmail.com
: 
: That fixed split_vma(). Alternating PROT_EXEC in setup introduces the
: same assumption elsewhere: RW and RWX both become RWX, allowing adjacent
: mappings to merge. The parent then cannot find the expected three-page
: VMAs and the test fails during setup, before testing procfs tearing.
: 
: Yes, the focused x86-64 check explicitly enabled READ_IMPLIES_EXEC to
: exercise this behavior. It wasn't tested on old ARM hardware. But I
: think we should preserve the existing support for those machines.
: Populating writable, then removing write permission from alternate
: mappings, preserves both RSS and the required VMA boundaries.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/1] selftests/proc: use RSS in /proc/pid/smaps_rollup tearing tests
  2026-11-02 16:01     ` Andrew Morton
@ 2026-11-02 16:11       ` Suren Baghdasaryan
  2026-11-02 16:15         ` Suren Baghdasaryan
  0 siblings, 1 reply; 10+ messages in thread
From: Suren Baghdasaryan @ 2026-11-02 16:11 UTC (permalink / raw)
  To: Andrew Morton
  Cc: david, ljs, jannh, liam, willy, paulmck, pfalcato, usama.arif,
	vbabka, linux-fsdevel, yi1.lai, oe-lkp, lkp, linux-kernel

On Mon, Nov 2, 2026 at 8:01 AM Andrew Morton <akpm@linux-foundation.org> wrote:
>
> On Mon, 2 Nov 2026 07:43:17 -0800 Suren Baghdasaryan <surenb@google.com> wrote:
>
> > > :
> > > : The patched userspace test passed all six cases on an existing
> > > : x86-64 6.18.57 kernel, with a PID-namespace adjustment. That kernel
> > > : predates ca5480fb53fa, so this checks selftest behavior, not the
> > > : intended kernel's procfs changes. Separate syscall tests on that
> > > : kernel confirmed the EXEC-merging and memlock failure cases.
> >
> > I'm guessing your bot was using personality() to make the tests fail.
> > Again, I'm not sure we should handle such use case. Should we?
>
>
> : The concern is pre-ARMv6 CPUs, where READ_IMPLIES_EXEC is set by
> : default. Nobody needs to call personality() to encounter this there.
> :
> : We already addressed this in 0685630fdccb ("selftests/proc: make
> : proc-maps-race work with READ_IMPLIES_EXEC"):
> :
> : https://lore.kernel.org/r/20260808200312.6326-1-kmehltretter@gmail.com
> :
> : That fixed split_vma(). Alternating PROT_EXEC in setup introduces the
> : same assumption elsewhere: RW and RWX both become RWX, allowing adjacent
> : mappings to merge. The parent then cannot find the expected three-page
> : VMAs and the test fails during setup, before testing procfs tearing.
> :
> : Yes, the focused x86-64 check explicitly enabled READ_IMPLIES_EXEC to
> : exercise this behavior. It wasn't tested on old ARM hardware. But I
> : think we should preserve the existing support for those machines.
> : Populating writable, then removing write permission from alternate
> : mappings, preserves both RSS and the required VMA boundaries.

Ah, I see now why handling READ_IMPLIES_EXEC is needed. Then your
complete fix looks fine. Perhaps we should mention this pre-ARMv6 CPU
detail in the changelog of your fix to explain why READ_IMPLIES_EXEC
is important here?


>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/1] selftests/proc: use RSS in /proc/pid/smaps_rollup tearing tests
  2026-11-02 16:11       ` Suren Baghdasaryan
@ 2026-11-02 16:15         ` Suren Baghdasaryan
  0 siblings, 0 replies; 10+ messages in thread
From: Suren Baghdasaryan @ 2026-11-02 16:15 UTC (permalink / raw)
  To: Andrew Morton
  Cc: david, ljs, jannh, liam, willy, paulmck, pfalcato, usama.arif,
	vbabka, linux-fsdevel, yi1.lai, oe-lkp, lkp, linux-kernel

On Mon, Nov 2, 2026 at 8:11 AM Suren Baghdasaryan <surenb@google.com> wrote:
>
> On Mon, Nov 2, 2026 at 8:01 AM Andrew Morton <akpm@linux-foundation.org> wrote:
> >
> > On Mon, 2 Nov 2026 07:43:17 -0800 Suren Baghdasaryan <surenb@google.com> wrote:
> >
> > > > :
> > > > : The patched userspace test passed all six cases on an existing
> > > > : x86-64 6.18.57 kernel, with a PID-namespace adjustment. That kernel
> > > > : predates ca5480fb53fa, so this checks selftest behavior, not the
> > > > : intended kernel's procfs changes. Separate syscall tests on that
> > > > : kernel confirmed the EXEC-merging and memlock failure cases.
> > >
> > > I'm guessing your bot was using personality() to make the tests fail.
> > > Again, I'm not sure we should handle such use case. Should we?
> >
> >
> > : The concern is pre-ARMv6 CPUs, where READ_IMPLIES_EXEC is set by
> > : default. Nobody needs to call personality() to encounter this there.
> > :
> > : We already addressed this in 0685630fdccb ("selftests/proc: make
> > : proc-maps-race work with READ_IMPLIES_EXEC"):
> > :
> > : https://lore.kernel.org/r/20260808200312.6326-1-kmehltretter@gmail.com
> > :
> > : That fixed split_vma(). Alternating PROT_EXEC in setup introduces the
> > : same assumption elsewhere: RW and RWX both become RWX, allowing adjacent
> > : mappings to merge. The parent then cannot find the expected three-page
> > : VMAs and the test fails during setup, before testing procfs tearing.
> > :
> > : Yes, the focused x86-64 check explicitly enabled READ_IMPLIES_EXEC to
> > : exercise this behavior. It wasn't tested on old ARM hardware. But I
> > : think we should preserve the existing support for those machines.
> > : Populating writable, then removing write permission from alternate
> > : mappings, preserves both RSS and the required VMA boundaries.
>
> Ah, I see now why handling READ_IMPLIES_EXEC is needed. Then your
> complete fix looks fine. Perhaps we should mention this pre-ARMv6 CPU
> detail in the changelog of your fix to explain why READ_IMPLIES_EXEC
> is important here?

I guess I have to ask whether you want to post your fix as a followup
to mine or if I should fold them into one patch and post a v3. What's
your preference?

>
>
> >

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-11-02 16:16 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-01 15:45 [PATCH v2 1/1] selftests/proc: use RSS in /proc/pid/smaps_rollup tearing tests Suren Baghdasaryan
2026-11-01 19:01 ` Andrew Morton
2026-11-02 13:08   ` Pedro Falcato
2026-11-02 15:31     ` Suren Baghdasaryan
2026-11-02 15:43   ` Suren Baghdasaryan
2026-11-02 16:01     ` Andrew Morton
2026-11-02 16:11       ` Suren Baghdasaryan
2026-11-02 16:15         ` Suren Baghdasaryan
2026-11-02 13:26 ` Pedro Falcato
2026-11-02 15:59   ` Suren Baghdasaryan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®