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 |
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 ...
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 > >
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 --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, +};
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