* [LTP] [PATCH] madvise06: make bug detection more reliable
@ 2016-07-22 10:56 Jan Stancek
2016-08-01 10:12 ` Jan Stancek
0 siblings, 1 reply; 2+ messages in thread
From: Jan Stancek @ 2016-07-22 10:56 UTC (permalink / raw)
To: ltp
1. set up memory cgroup
This allows us to get swapped memory faster, and also
eliminates problems with running testcase on big systems.
2. check for expected effects in a loop
madvise_willneed() reads memory asynchronously, so we check
multiple times with delay in-between. Because we can't
distinguish between bad kernel and slow I/O, bad kernel
will make test check for 5 seconds before giving up.
As last resort we check presence of first page.
Signed-off-by: Jan Stancek <jstancek@redhat.com>
---
testcases/kernel/syscalls/madvise/madvise06.c | 142 ++++++++++++++++++--------
1 file changed, 101 insertions(+), 41 deletions(-)
diff --git a/testcases/kernel/syscalls/madvise/madvise06.c b/testcases/kernel/syscalls/madvise/madvise06.c
index 6b081fddf5eb..ddd1814df5c5 100644
--- a/testcases/kernel/syscalls/madvise/madvise06.c
+++ b/testcases/kernel/syscalls/madvise/madvise06.c
@@ -34,29 +34,82 @@
*/
#include <errno.h>
+#include <stdio.h>
+#include <sys/mount.h>
#include <sys/sysinfo.h>
#include "tst_test.h"
-#define GB_SZ (1024*1024*1024)
+#define CHUNK_SZ (400*1024*1024L)
+#define CHUNK_PAGES (CHUNK_SZ / pg_sz)
+#define PASS_THRESHOLD (CHUNK_SZ / 4)
-static long dst_max;
+#define MNT_NAME "memory"
+#define GROUP_NAME "madvise06"
+
+static const char drop_caches_fname[] = "/proc/sys/vm/drop_caches";
static int pg_sz;
+static void check_path(const char *path)
+{
+ if (access(path, R_OK | W_OK))
+ tst_brk(TCONF, "file needed: %s\n", path);
+}
+
static void setup(void)
{
- struct sysinfo sys_buf;
-
- sysinfo(&sys_buf);
-
- if (sys_buf.totalram < 2L * GB_SZ)
- tst_brk(TCONF, "Test requires more than 2GB of RAM");
- if (sys_buf.totalram > 100L * GB_SZ)
- tst_brk(TCONF, "System RAM is too large, skip test");
-
- dst_max = sys_buf.totalram / GB_SZ;
- tst_res(TINFO, "dst_max = %ld", dst_max);
+ struct sysinfo sys_buf_start;
pg_sz = getpagesize();
+
+ check_path(drop_caches_fname);
+ tst_res(TINFO, "dropping caches");
+ sync();
+ SAFE_FILE_PRINTF(drop_caches_fname, "3");
+
+ sysinfo(&sys_buf_start);
+ if (sys_buf_start.freeram < 2 * CHUNK_SZ)
+ tst_brk(TCONF, "System RAM is too small, skip test");
+ if (sys_buf_start.freeswap < 2 * CHUNK_SZ)
+ tst_brk(TCONF, "System swap is too small");
+
+ SAFE_MKDIR(MNT_NAME, 0700);
+ if (mount("memory", MNT_NAME, "cgroup", 0, "memory") == -1) {
+ if (errno == ENODEV || errno == ENOENT)
+ tst_brk(TCONF, "memory cgroup needed");
+ }
+ SAFE_MKDIR(MNT_NAME"/"GROUP_NAME, 0700);
+
+ check_path("/proc/self/oom_score_adj");
+ check_path(MNT_NAME"/"GROUP_NAME"/memory.limit_in_bytes");
+ check_path(MNT_NAME"/"GROUP_NAME"/memory.swappiness");
+ check_path(MNT_NAME"/"GROUP_NAME"/tasks");
+
+ SAFE_FILE_PRINTF("/proc/self/oom_score_adj", "%d", -1000);
+ SAFE_FILE_PRINTF(MNT_NAME"/"GROUP_NAME"/memory.limit_in_bytes", "%ld\n",
+ PASS_THRESHOLD);
+ SAFE_FILE_PRINTF(MNT_NAME"/"GROUP_NAME"/memory.swappiness", "60");
+ SAFE_FILE_PRINTF(MNT_NAME"/"GROUP_NAME"/tasks", "%d\n", getpid());
+}
+
+static void cleanup(void)
+{
+ FILE *f = fopen(MNT_NAME"/tasks", "w");
+
+ if (f) {
+ fprintf(f, "%d\n", getpid());
+ fclose(f);
+ }
+ rmdir(MNT_NAME"/"GROUP_NAME);
+ umount(MNT_NAME);
+}
+
+static void dirty_pages(char *ptr, long size)
+{
+ long i;
+ long pages = size / pg_sz;
+
+ for (i = 0; i < pages; i++)
+ ptr[i * pg_sz] = 'x';
}
static int get_page_fault_num(void)
@@ -66,46 +119,52 @@ static int get_page_fault_num(void)
SAFE_FILE_SCANF("/proc/self/stat",
"%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %d",
&pg);
-
return pg;
}
static void test_advice_willneed(void)
{
- int i;
- char *src;
- char *dst[100];
- int page_fault_num_1;
- int page_fault_num_2;
+ int loops = 50;
+ char *target;
+ long swapcached_start, swapcached;
+ int page_fault_num_1, page_fault_num_2;
- /* allocate source memory (1GB only) */
- src = SAFE_MMAP(NULL, 1 * GB_SZ, PROT_READ | PROT_WRITE,
+ target = SAFE_MMAP(NULL, CHUNK_SZ, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS,
-1, 0);
+ dirty_pages(target, CHUNK_SZ);
- /* allocate destination memory (array) */
- for (i = 0; i < dst_max; ++i)
- dst[i] = SAFE_MMAP(NULL, 1 * GB_SZ,
- PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_ANONYMOUS,
- -1, 0);
+ SAFE_FILE_LINES_SCANF("/proc/meminfo", "SwapCached: %ld",
+ &swapcached_start);
+ tst_res(TINFO, "SwapCached (before madvise): %ld", swapcached_start);
- /* memmove source to each destination memories (for SWAP-OUT) */
- for (i = 0; i < dst_max; ++i)
- memmove(dst[i], src, 1 * GB_SZ);
-
- tst_res(TINFO, "PageFault(no madvice): %d", get_page_fault_num());
-
- /* Do madvice() to dst[0] */
- TEST(madvise(dst[0], pg_sz, MADV_WILLNEED));
+ TEST(madvise(target, CHUNK_SZ, MADV_WILLNEED));
if (TEST_RETURN == -1)
tst_brk(TBROK | TERRNO, "madvise failed");
+ do {
+ loops--;
+ usleep(100000);
+ SAFE_FILE_LINES_SCANF("/proc/meminfo", "SwapCached: %ld",
+ &swapcached);
+ } while (swapcached < swapcached_start + PASS_THRESHOLD / 1024
+ && loops > 0);
+
+ tst_res(TINFO, "SwapCached (after madvise): %ld", swapcached);
+ if (swapcached > swapcached_start + PASS_THRESHOLD / 1024) {
+ tst_res(TPASS, "Regression test pass");
+ SAFE_MUNMAP(target, CHUNK_SZ);
+ return;
+ }
+
+ /*
+ * We may have hit a bug or we just have slow I/O,
+ * try accessing first page.
+ */
page_fault_num_1 = get_page_fault_num();
tst_res(TINFO, "PageFault(madvice / no mem access): %d",
page_fault_num_1);
-
- *dst[0] = 'a';
+ target[0] = 'a';
page_fault_num_2 = get_page_fault_num();
tst_res(TINFO, "PageFault(madvice / mem access): %d",
page_fault_num_2);
@@ -115,13 +174,14 @@ static void test_advice_willneed(void)
else
tst_res(TPASS, "Regression test pass");
- SAFE_MUNMAP(src, 1 * GB_SZ);
- for (i = 0; i < dst_max; ++i)
- SAFE_MUNMAP(dst[i], 1 * GB_SZ);
+ SAFE_MUNMAP(target, CHUNK_SZ);
}
static struct tst_test test = {
- .tid = "madvice06",
+ .tid = "madvise06",
.test_all = test_advice_willneed,
.setup = setup,
+ .cleanup = cleanup,
+ .needs_tmpdir = 1,
+ .needs_root = 1,
};
--
1.8.3.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [LTP] [PATCH] madvise06: make bug detection more reliable
2016-07-22 10:56 [LTP] [PATCH] madvise06: make bug detection more reliable Jan Stancek
@ 2016-08-01 10:12 ` Jan Stancek
0 siblings, 0 replies; 2+ messages in thread
From: Jan Stancek @ 2016-08-01 10:12 UTC (permalink / raw)
To: ltp
----- Original Message -----
> From: "Jan Stancek" <jstancek@redhat.com>
> To: ltp@lists.linux.it
> Cc: liwan@redhat.com
> Sent: Friday, 22 July, 2016 12:56:41 PM
> Subject: [LTP] [PATCH] madvise06: make bug detection more reliable
>
> 1. set up memory cgroup
> This allows us to get swapped memory faster, and also
> eliminates problems with running testcase on big systems.
>
> 2. check for expected effects in a loop
> madvise_willneed() reads memory asynchronously, so we check
> multiple times with delay in-between. Because we can't
> distinguish between bad kernel and slow I/O, bad kernel
> will make test check for 5 seconds before giving up.
> As last resort we check presence of first page.
>
> Signed-off-by: Jan Stancek <jstancek@redhat.com>
> ---
> testcases/kernel/syscalls/madvise/madvise06.c | 142
> ++++++++++++++++++--------
> 1 file changed, 101 insertions(+), 41 deletions(-)
>
I tested this on 4.7-rc7 and pushed.
Regards,
Jan
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-08-01 10:12 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-22 10:56 [LTP] [PATCH] madvise06: make bug detection more reliable Jan Stancek
2016-08-01 10:12 ` Jan Stancek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox