diff mbox series

[v2] syscalls/mlock05: add mlock test for locking and pre-faulting of memory

Message ID 20240429133336.3166386-1-fstornio@redhat.com
State Changes Requested
Headers show
Series [v2] syscalls/mlock05: add mlock test for locking and pre-faulting of memory | expand

Commit Message

Filippo Storniolo April 29, 2024, 1:33 p.m. UTC
check VmRSS and VmLck variables from /proc/$pid/status.
VmRSS size should at least as big as the memory allocation.
VmLck size should be equal to the size of the memory allocation.

Co-developed-by: Dennis Brendel <dbrendel@redhat.com>
Signed-off-by: Filippo Storniolo <fstornio@redhat.com>
---
 runtest/syscalls                           |  1 +
 testcases/kernel/syscalls/mlock/.gitignore |  1 +
 testcases/kernel/syscalls/mlock/mlock05.c  | 60 ++++++++++++++++++++++
 3 files changed, 62 insertions(+)
 create mode 100644 testcases/kernel/syscalls/mlock/mlock05.c

Comments

Cyril Hrubis April 29, 2024, 1:48 p.m. UTC | #1
Hi!
> check VmRSS and VmLck variables from /proc/$pid/status.
> VmRSS size should at least as big as the memory allocation.
> VmLck size should be equal to the size of the memory allocation.

Now the test looks good, however I managed to make it fail. The test
fails if you run it with large enough -i paramater, for me running
'./mlock05 -i 10000' tend to produce failures at the end of the testrun:

tst_test.c:1741: TINFO: LTP version: 20240129-192-geca801321
tst_test.c:1625: TINFO: Timeout per run is 0h 00m 30s
mlock05.c:49: TPASS: Expect: (VmRSS=1048576) >= (MMAPLEN=1048576)
mlock05.c:52: TPASS: VmLck == MMAPLEN (1048576)
...
mlock05.c:52: TPASS: VmLck == MMAPLEN (1048576)
mlock05.c:49: TFAIL: Expect: (VmRSS=983040) >= (MMAPLEN=1048576)
mlock05.c:52: TPASS: VmLck == MMAPLEN (1048576)
mlock05.c:49: TFAIL: Expect: (VmRSS=983040) >= (MMAPLEN=1048576)
mlock05.c:52: TPASS: VmLck == MMAPLEN (1048576)

Summary:
passed   18332
failed   1668
broken   0
skipped  0
warnings 0
...
Filippo Storniolo May 2, 2024, 9:12 a.m. UTC | #2
Hi Cyril, thank you for your review.

After some investigation, I realized the issue is caused by the
unreliability of the VmRSS field in /proc/$pid/status.
Documentation suggests to use /proc/$pid/smaps for reliable information.

This file contains information about each memory mapping, so it contains
multiple instances of the VmRss field (In this file is simply referred as
Rss).

I managed to run the test without any failures using a custom function.
What we need to do is to iterate through the memory mappings until we find
the one we need. We can use the memory address retrieved by mmap to locate
the desired one.

Once we find the mapping, we can then search the Rss field.

This is the output I had using this approach:

TPASS: Expect: (VmRSS=1048576) >= (MMAPLEN=1048576)
TPASS: VmLck == MMAPLEN (1048576)

Summary:
passed  20000
failed   0
broken   0
skipped  0
warnings 0

Do you think this can work as a solution or you prefer another way around?

F. Storniolo



On Mon, Apr 29, 2024 at 3:49 PM Cyril Hrubis <chrubis@suse.cz> wrote:

> Hi!
> > check VmRSS and VmLck variables from /proc/$pid/status.
> > VmRSS size should at least as big as the memory allocation.
> > VmLck size should be equal to the size of the memory allocation.
>
> Now the test looks good, however I managed to make it fail. The test
> fails if you run it with large enough -i paramater, for me running
> './mlock05 -i 10000' tend to produce failures at the end of the testrun:
>
> tst_test.c:1741: TINFO: LTP version: 20240129-192-geca801321
> tst_test.c:1625: TINFO: Timeout per run is 0h 00m 30s
> mlock05.c:49: TPASS: Expect: (VmRSS=1048576) >= (MMAPLEN=1048576)
> mlock05.c:52: TPASS: VmLck == MMAPLEN (1048576)
> ...
> mlock05.c:52: TPASS: VmLck == MMAPLEN (1048576)
> mlock05.c:49: TFAIL: Expect: (VmRSS=983040) >= (MMAPLEN=1048576)
> mlock05.c:52: TPASS: VmLck == MMAPLEN (1048576)
> mlock05.c:49: TFAIL: Expect: (VmRSS=983040) >= (MMAPLEN=1048576)
> mlock05.c:52: TPASS: VmLck == MMAPLEN (1048576)
>
> Summary:
> passed   18332
> failed   1668
> broken   0
> skipped  0
> warnings 0
> ...
>
> --
> Cyril Hrubis
> chrubis@suse.cz
>
>
Cyril Hrubis May 2, 2024, 10:09 a.m. UTC | #3
Hi!
> After some investigation, I realized the issue is caused by the
> unreliability of the VmRSS field in /proc/$pid/status.
> Documentation suggests to use /proc/$pid/smaps for reliable information.
> 
> This file contains information about each memory mapping, so it contains
> multiple instances of the VmRss field (In this file is simply referred as
> Rss).
> 
> I managed to run the test without any failures using a custom function.
> What we need to do is to iterate through the memory mappings until we find
> the one we need. We can use the memory address retrieved by mmap to locate
> the desired one.
> 
> Once we find the mapping, we can then search the Rss field.
> 
> This is the output I had using this approach:
> 
> TPASS: Expect: (VmRSS=1048576) >= (MMAPLEN=1048576)
> TPASS: VmLck == MMAPLEN (1048576)
> 
> Summary:
> passed  20000
> failed   0
> broken   0
> skipped  0
> warnings 0
> 
> Do you think this can work as a solution or you prefer another way around?

Looking up the right mapping and checking that the size of the resident
set is as expected sounds good to me.
diff mbox series

Patch

diff --git a/runtest/syscalls b/runtest/syscalls
index 252123d8b..05a52fc8f 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -781,6 +781,7 @@  mlock01 mlock01
 mlock02 mlock02
 mlock03 mlock03 -i 20
 mlock04 mlock04
+mlock05 mlock05
 
 mlock201 mlock201
 mlock202 mlock202
diff --git a/testcases/kernel/syscalls/mlock/.gitignore b/testcases/kernel/syscalls/mlock/.gitignore
index 306574bbc..1872229b8 100644
--- a/testcases/kernel/syscalls/mlock/.gitignore
+++ b/testcases/kernel/syscalls/mlock/.gitignore
@@ -2,3 +2,4 @@ 
 /mlock02
 /mlock03
 /mlock04
+/mlock05
diff --git a/testcases/kernel/syscalls/mlock/mlock05.c b/testcases/kernel/syscalls/mlock/mlock05.c
new file mode 100644
index 000000000..2475cb333
--- /dev/null
+++ b/testcases/kernel/syscalls/mlock/mlock05.c
@@ -0,0 +1,60 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright Red Hat
+ * Author: Filippo Storniolo <fstornio@redhat.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Verify mlock() causes pre-faulting of PTEs and prevent memory to be swapped out.
+ *
+ * Checks the variables VmRSS and VmLck in /proc/$pid/status after the
+ * mlock syscall:
+ * - VmRSS size should be at least as big as the memory allocation
+ * - VmLck size should be equal to the size of the memory allocation
+ */
+
+#include "tst_test.h"
+
+#define MMAPLEN			(1UL<<20)
+
+static void verify_mlock(void)
+{
+	unsigned long VmRSS_before;
+	unsigned long VmRSS_after;
+	unsigned long VmLck_before;
+	unsigned long VmLck_after;
+	unsigned long VmRSS;
+	unsigned long VmLck;
+	char *buf;
+
+	buf = SAFE_MMAP(NULL, MMAPLEN, PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+	SAFE_FILE_LINES_SCANF("/proc/self/status", "VmRSS: %lu", &VmRSS_before);
+	SAFE_FILE_LINES_SCANF("/proc/self/status", "VmLck: %lu", &VmLck_before);
+
+	SAFE_MLOCK(buf, MMAPLEN);
+
+	SAFE_FILE_LINES_SCANF("/proc/self/status", "VmRSS: %lu", &VmRSS_after);
+	SAFE_FILE_LINES_SCANF("/proc/self/status", "VmLck: %lu", &VmLck_after);
+
+	VmRSS = VmRSS_after - VmRSS_before;
+	VmLck = VmLck_after - VmLck_before;
+
+	// Convertion from KiB to B
+	VmRSS *= 1024;
+	VmLck *= 1024;
+
+	TST_EXP_EXPR(VmRSS >= MMAPLEN,
+				"(VmRSS=%lu) >= (MMAPLEN=%lu)", VmRSS, MMAPLEN);
+
+	TST_EXP_EQ_LU(VmLck, MMAPLEN);
+
+	SAFE_MUNLOCK(buf, MMAPLEN);
+	SAFE_MUNMAP(buf, MMAPLEN);
+}
+
+static struct tst_test test = {
+	.test_all = verify_mlock,
+};