[LTP] [PATCH] madvise09: Add MADV_FREE test

Cyril Hrubis chrubis@suse.cz
Tue Mar 21 14:03:13 CET 2017


Hi!
Ok to commit with these changes against v2?

diff --git a/testcases/kernel/syscalls/madvise/madvise09.c b/testcases/kernel/syscalls/madvise/madvise09.c
index 0339086..45a14a0 100644
--- a/testcases/kernel/syscalls/madvise/madvise09.c
+++ b/testcases/kernel/syscalls/madvise/madvise09.c
@@ -52,6 +52,7 @@
 #include <signal.h>
 #include <errno.h>
 #include <stdio.h>
+#include <ctype.h>
 
 #include "tst_test.h"
 #include "lapi/mmap.h"
@@ -64,14 +65,16 @@ static char limit_in_bytes_path[PATH_MAX];
 static char memsw_limit_in_bytes_path[PATH_MAX];
 
 static size_t page_size;
+static int sleep_between_faults;
 
 #define PAGES 32
+#define TOUCHED_PAGE1 0
+#define TOUCHED_PAGE2 10
 
 static void memory_pressure_child(void)
 {
 	size_t i, page_size = getpagesize();
 	char *ptr;
-	int sleep = 1;
 
 	for (;;) {
 		ptr = mmap(NULL, 500 * page_size, PROT_READ | PROT_WRITE,
@@ -79,10 +82,8 @@ static void memory_pressure_child(void)
 
 		for (i = 0; i < 500; i++) {
 			ptr[i * page_size] = i % 100;
-			usleep(sleep);
+			usleep(sleep_between_faults);
 		}
-
-		sleep++;
 	}
 
 	abort();
@@ -111,6 +112,46 @@ static int count_freed(char *ptr)
 	return ret;
 }
 
+static int check_page_baaa(char *ptr)
+{
+	unsigned int i;
+
+	if (ptr[0] != 'b') {
+		tst_res(TINFO, "%p unexpected %c (%i) at 0 expected 'b'",
+			ptr, isprint(ptr[0]) ? ptr[0] : ' ', ptr[0]);
+		return 1;
+	}
+
+	for (i = 1; i < page_size; i++) {
+		if (ptr[i] != 'a') {
+			tst_res(TINFO,
+				"%p unexpected %c (%i) at %i expected 'a'",
+				ptr, isprint(ptr[i]) ? ptr[i] : ' ',
+				ptr[i], i);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static int check_page(char *ptr, char val)
+{
+	unsigned int i;
+
+	for (i = 0; i < page_size; i++) {
+		if (ptr[i] != val) {
+			tst_res(TINFO,
+				"%p unexpected %c (%i) at %i expected %c (%i)",
+				ptr, isprint(ptr[i]) ? ptr[i] : ' ', ptr[i], i,
+				isprint(val) ? val : ' ', val);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
 static void child(void)
 {
 	size_t i;
@@ -139,8 +180,8 @@ static void child(void)
 	else
 		tst_res(TPASS, "MADV_FREE pages were not freed immediatelly");
 
-	ptr[0] = 'b';
-	ptr[10 * page_size] = 'b';
+	ptr[TOUCHED_PAGE1 * page_size] = 'b';
+	ptr[TOUCHED_PAGE2 * page_size] = 'b';
 
 	usage = 8 * 1024 * 1024;
 	tst_res(TINFO, "Setting memory limits to %u %u", usage, 2 * usage);
@@ -151,6 +192,8 @@ static void child(void)
 	SAFE_FILE_PRINTF(memsw_limit_in_bytes_path, "%u", 2 * usage);
 
 	do {
+		sleep_between_faults++;
+
 		pid = SAFE_FORK();
 		if (!pid)
 			memory_pressure_child();
@@ -160,21 +203,33 @@ static void child(void)
 		SAFE_WAIT(&status);
 	} while (retries++ < 10 && count_freed(ptr) == 0);
 
-	if (ptr[0] == 0 || ptr[10 * page_size] == 0)
-		tst_res(TFAIL, "Page modified after MADV_FREE was freed");
-	else
-		tst_res(TPASS, "Page modified after MADV_FREE was not freed");
-
 	char map[PAGES+1];
 	unsigned int freed = 0;
+	unsigned int corrupted = 0;
 
 	for (i = 0; i < PAGES; i++) {
+		char exp_val;
+
 		if (ptr[i * page_size]) {
+			exp_val = 'a';
 			map[i] = 'p';
 		} else {
+			exp_val = 0;
 			map[i] = '_';
 			freed++;
 		}
+
+		if (i != TOUCHED_PAGE1 && i != TOUCHED_PAGE2) {
+			if (check_page(ptr + i * page_size, exp_val)) {
+				map[i] = '?';
+				corrupted++;
+			}
+		} else {
+			if (check_page_baaa(ptr + i * page_size)) {
+				map[i] = '?';
+				corrupted++;
+			}
+		}
 	}
 	map[PAGES] = '\0';
 
@@ -185,6 +240,11 @@ static void child(void)
 	else
 		tst_res(TFAIL, "No MADV_FREE page was freed on low memory");
 
+	if (corrupted)
+		tst_res(TFAIL, "Found corrupted page");
+	else
+		tst_res(TPASS, "All pages have expected content");
+
 	SAFE_FILE_PRINTF(memsw_limit_in_bytes_path, "%u", old_memsw_limit);
 	SAFE_FILE_PRINTF(limit_in_bytes_path, "%u", old_limit);
 

-- 
Cyril Hrubis
chrubis@suse.cz


More information about the ltp mailing list