Skip to contentSkip to conversation

mm/oom: extend the coverage of OOM

PATCH Superseded Zhouping Liu 3 participants 12 messages Mar 14, 2013 – Mar 15, 2013 1 message not in the archive

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

cover mm/oom: extend the coverage of OOM

The patch set updated all OOM testcases, and added a new testcase.

Inside old version, OOM only test MPOL_MBIND mempolicy in NUMA system, and the combination of CPUSET, MEMCG & NUMA is complex, and not clear. Also CPUSET is only used in NUMA system.

The patch set adjust them, now we can coverage the below tests:
1) OOM under normal - oom01
2) OOM under all mempolicy - oom02
3) OOM under MEMCG - oom03
4) OOM under CPUSET - oom04
5) OOM under CPUSET & MEMCG - oom05

I have tested the patch set, no any regressions found.

Zhouping Liu (5):
lib/mem: modified _gather_cpus() as _gather_node_cpus() mm/oom02: modified 'OOM for NUMA' as 'OOM for mempolicy' mm/oom0[3|4]: added 'OOM for CPUSET' and updated 'OOM with MEMCG &
numa'
lib/mem: updated testoom() and oom() funcs
mm/oom05: new testcase

 runtest/mm                         |   1 +
 testcases/kernel/mem/include/mem.h |   6 +-
 testcases/kernel/mem/lib/mem.c     | 101 ++++++++++++++++++-------
 testcases/kernel/mem/oom/oom01.c   |   6 +-
 testcases/kernel/mem/oom/oom02.c   |  20 +++--
 testcases/kernel/mem/oom/oom03.c   |  28 ++++++-
 testcases/kernel/mem/oom/oom04.c   |  63 +++++++---------
 testcases/kernel/mem/oom/oom05.c   | 151 +++++++++++++++++++++++++++++++++++++
 8 files changed, 296 insertions(+), 80 deletions(-)
 create mode 100644 testcases/kernel/mem/oom/oom05.c
Signature · 12 lines
1.7.11.7


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list
#1 lore raw

PATCH 1/5 lib/mem: modified _gather_cpus() as _gather_node_cpus()

The previous _gather_cpus() tried to collect all the specified node's cpus, but it didn't pay attention to the offline cpus, if one cpu in the specified node were offline, it can't write the cpu number to cgroups/*.cpus, and return -EINVAL.

The patch fixed it, and modified the function name, as the new name make more sense.

---
 testcases/kernel/mem/lib/mem.c | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)
testcases/kernel/mem/lib/mem.c +27 -5
index a827b25..29de64a 100644
@@ -481,20 +481,42 @@ void ksm_usage(void)
 
 /* cpuset/memcg */
 
-static void _gather_cpus(char *cpus, long nd)
+static void _gather_node_cpus(char *cpus, long nd)
 {
 	int ncpus = 0;
-	int i;
+	int fd, i;
+	long online;
 	char buf[BUFSIZ];
+	char path[BUFSIZ], path1[BUFSIZ];
 
 	while (path_exist(PATH_SYS_SYSTEM "/cpu/cpu%d", ncpus))
 		ncpus++;
 
-	for (i = 0; i < ncpus; i++)
-		if (path_exist(PATH_SYS_SYSTEM "/node/node%ld/cpu%d", nd, i)) {
+	for (i = 0; i < ncpus; i++) {
+		snprintf(path, BUFSIZ,
+			 PATH_SYS_SYSTEM "/node/node%ld/cpu%d", nd, i);
+		if (path_exist(path, nd, i)) {
+			snprintf(path1, BUFSIZ, "%s/online", path);
+			/*
+			 * No cpu0/online knob, as it can't support to
+			 * on/offline cpu0, so if the 'nd' node contains
+			 * cpu0, it should skip to check cpu0/online's value.
+			 */
+			if (i == 0)
+				goto  next;
+			fd = open(path1, O_RDONLY);
+			if (fd == -1)
+				tst_brkm(TBROK|TERRNO, cleanup,
+					 "open %s", path1);
+			read_file(path1, buf);
+			online = SAFE_STRTOL(cleanup, buf, 0, 1);
+			if (online == 0)
+				continue;
+next:
 			sprintf(buf, "%d,", i);
 			strcat(cpus, buf);
 		}
+	}
 	/* Remove the trailing comma. */
 	cpus[strlen(cpus) - 1] = '\0';
 }
@@ -563,7 +585,7 @@ void write_cpusets(long nd)
 	snprintf(buf, BUFSIZ, "%ld", nd);
 	write_cpuset_files(CPATH_NEW, "mems", buf);
 
-	_gather_cpus(cpus, nd);
+	_gather_node_cpus(cpus, nd);
 	write_cpuset_files(CPATH_NEW, "cpus", cpus);
 
 	snprintf(buf, BUFSIZ, "%d", getpid());
Signature · 12 lines
1.7.11.7


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list
#2 lore raw

PATCH 2/5 mm/oom02: modified 'OOM for NUMA' as 'OOM for mempolicy'

NUMA mechanism can be interpreted as 'memory policy', there are several mempolicys, such as MPOL_BIND, MPOL_INTERLEAVE, MPOL_PREFERRED etc, not only MPOL_BIND, so the patch extended OOM on NUMA system, added MPOL_INTERLEAVE and MPOL_PREFERRED mempolicy.

And the patch also moved 'set_mempolicy()' from child process, and made it executed inside testoom() func, which is easy to control.

---
 testcases/kernel/mem/lib/mem.c   | 56 ++++++++++++++++++++++++++++------------
 testcases/kernel/mem/oom/oom02.c | 20 +++++++++-----
 2 files changed, 52 insertions(+), 24 deletions(-)
testcases/kernel/mem/lib/mem.c +39 -17
index 29de64a..a71bc90 100644
@@ -64,32 +64,17 @@ void oom(int testcase, int mempolicy, int lite)
 {
 	pid_t pid;
 	int status;
-#if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
-	&& HAVE_MPOL_CONSTANTS
-	unsigned long nmask = 0;
-	unsigned int node;
-
-	if (mempolicy)
-		node = get_a_numa_node(cleanup);
-	nmask += 1 << node;
-#endif
 
 	switch (pid = fork()) {
 	case -1:
 		tst_brkm(TBROK | TERRNO, cleanup, "fork");
 	case 0:
-#if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
-	&& HAVE_MPOL_CONSTANTS
-		if (mempolicy)
-			if (set_mempolicy(MPOL_BIND, &nmask, MAXNODES) == -1)
-				tst_brkm(TBROK | TERRNO, cleanup,
-					 "set_mempolicy");
-#endif
 		_test_alloc(testcase, lite);
 		exit(0);
 	default:
 		break;
 	}
+
 	tst_resm(TINFO, "expected victim is %d.", pid);
 	if (waitpid(-1, &status, 0) == -1)
 		tst_brkm(TBROK | TERRNO, cleanup, "waitpid");
@@ -107,7 +92,44 @@ void oom(int testcase, int mempolicy, int lite)
 
 void testoom(int mempolicy, int lite, int numa)
 {
-	long nodes[MAXNODES];
+#if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
+	&& HAVE_MPOL_CONSTANTS
+	unsigned long nmask = 0;
+	unsigned int num_nodes, nodes[MAXNODES];
+	int ret;
+
+	if (mempolicy) {
+		ret = get_allowed_nodes_arr(NH_MEMS|NH_CPUS, &num_nodes, &nodes);
+		if (ret != 0)
+			tst_brkm(TBROK|TERRNO, cleanup,
+				 "get_allowed_nodes_arr");
+		if (num_nodes < 2) {
+			tst_resm(TINFO, "mempolicy need NUMA system support");
+			return;
+		}
+		switch(mempolicy) {
+		case MPOL_BIND:
+			/* bind the second node */
+			nmask = 1 << nodes[1];
+			break;
+		case MPOL_INTERLEAVE:
+		case MPOL_PREFERRED:
+			if (num_nodes == 2) {
+				tst_resm(TINFO, "The mempolicy need "
+					 "more than 2 numa nodes");
+				return;
+			} else {
+				/* Using the 2nd,3rd node */
+				nmask = (1 << nodes[1]) | (1 << nodes[2]);
+			}
+			break;
+		default:
+			tst_brkm(TBROK|TERRNO, cleanup, "Bad mempolicy mode");
+		}
+		if (set_mempolicy(mempolicy, &nmask, MAXNODES) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup, "set_mempolicy");
+	}
+#endif
 
 	if (numa && !mempolicy)
 		write_cpusets(get_a_numa_node(cleanup));
testcases/kernel/mem/oom/oom02.c +13 -7
index abd8aa2..31ec73f 100644
@@ -1,5 +1,5 @@
 /*
- * Out Of Memory (OOM) for NUMA
+ * Out Of Memory (OOM) for mempolicy - need NUMA system support
  *
  * The program is designed to cope with unpredictable like amount and
  * system physical memory, swap size and other VMM technology like KSM,
@@ -44,6 +44,8 @@ int TST_TOTAL = 1;
 
 #if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
 	&& HAVE_MPOL_CONSTANTS
+#include <numaif.h>
+
 int main(int argc, char *argv[])
 {
 	char *msg;
@@ -62,11 +64,14 @@ int main(int argc, char *argv[])
 	for (lc = 0; TEST_LOOPING(lc); lc++) {
 		tst_count = 0;
 
-		tst_resm(TINFO, "process mempolicy.");
-		testoom(1, 0, 1);
+		tst_resm(TINFO, "OOM on MPOL_BIND mempolicy...");
+		testoom(MPOL_BIND, 0, 1);
+
+		tst_resm(TINFO, "OOM on MPOL_INTERLEAVE mempolicy...");
+		testoom(MPOL_INTERLEAVE, 0, 1);
 
-		tst_resm(TINFO, "process cpuset.");
-		testoom(0, 0, 1);
+		tst_resm(TINFO, "OOM on MPOL_PREFERRED mempolicy...");
+		testoom(MPOL_PREFERRED, 0, 1);
 	}
 	cleanup();
 	tst_exit();
@@ -78,15 +83,16 @@ void setup(void)
 	tst_sig(FORK, DEF_HANDLER, cleanup);
 	TEST_PAUSE;
 
+	/* Judge a NUMA system through get_a_numa_node */
+	get_a_numa_node(NULL);
+
 	overcommit = get_sys_tune("overcommit_memory");
 	set_sys_tune("overcommit_memory", 1, 1);
-	mount_mem("cpuset", "cpuset", NULL, CPATH, CPATH_NEW);
 }
 
 void cleanup(void)
 {
 	set_sys_tune("overcommit_memory", overcommit, 0);
-	umount_mem(CPATH, CPATH_NEW);
 
 	TEST_CLEANUP;
 }
Signature · 12 lines
1.7.11.7


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list
#3 lore raw

PATCH 3/5 mm/oom0[3|4]: added 'OOM for CPUSET' and updated 'OOM with MEMCG & numa'

OOM with the combination of memcg & numa was moved to oom03, and the case is re-design to be used to test OOM with CPUSET.

The patch also introduce a new global var ISNUMA, which is easily used to recognize a NUMA system.

---
 testcases/kernel/mem/include/mem.h |  2 ++
 testcases/kernel/mem/lib/mem.c     |  2 ++
 testcases/kernel/mem/oom/oom03.c   | 24 +++++++++++++++
 testcases/kernel/mem/oom/oom04.c   | 63 ++++++++++++++++----------------------
 4 files changed, 54 insertions(+), 37 deletions(-)
testcases/kernel/mem/include/mem.h +2 -0
index 1233493..de51838 100644
@@ -24,6 +24,8 @@
 #define MLOCK			3
 #define KSM			4
 
+extern int ISNUMA;
+
 long overcommit;
 void oom(int testcase, int mempolicy, int lite);
 void testoom(int mempolicy, int lite, int numa);
testcases/kernel/mem/lib/mem.c +2 -0
index a71bc90..e99dae7 100644
@@ -24,6 +24,8 @@
 #include "mem.h"
 #include "numa_helper.h"
 
+int ISNUMA = 0; /* mark a NUMA system */
+
 /* OOM */
 
 static int _alloc_mem(long int length, int testcase)
testcases/kernel/mem/oom/oom03.c +24 -0
index 95e34d5..4365c2b 100644
@@ -40,6 +40,10 @@
 char *TCID = "oom03";
 int TST_TOTAL = 1;
 
+#if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
+	&& HAVE_MPOL_CONSTANTS
+#include <numaif.h>
+
 int main(int argc, char *argv[])
 {
 	char *msg;
@@ -76,6 +80,14 @@ int main(int argc, char *argv[])
 			write_file(MEMCG_SW_LIMIT, mem);
 			testoom(0, 1, 0);
 		}
+
+		/* OOM for MEMCG with mempolicy */
+		if (ISNUMA) {
+			tst_resm(TINFO, "OOM on MEMCG & mempolicy...");
+			testoom(MPOL_BIND, 0, 1);
+			testoom(MPOL_INTERLEAVE, 0, 1);
+			testoom(MPOL_PREFERRED, 0, 1);
+		}
 	}
 	cleanup();
 	tst_exit();
@@ -87,6 +99,10 @@ void setup(void)
 	tst_sig(FORK, DEF_HANDLER, cleanup);
 	TEST_PAUSE;
 
+	/* rough estimate a NUMA system by max_node id */
+	if (numa_max_node() > 0)
+		ISNUMA = 1;
+
 	overcommit = get_sys_tune("overcommit_memory");
 	set_sys_tune("overcommit_memory", 1, 1);
 	mount_mem("memcg", "cgroup", "memory", MEMCG_PATH, MEMCG_PATH_NEW);
@@ -99,3 +115,11 @@ void cleanup(void)
 
 	TEST_CLEANUP;
 }
+
+#else
+int main(void)
+{
+	tst_brkm(TCONF, NULL, "no NUMA development packages installed.");
+}
+#endif
+
testcases/kernel/mem/oom/oom04.c +26 -37

95 lines not on this page · raw message

Signature · 12 lines
1.7.11.7


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list
#4 lore raw

PATCH 4/5 lib/mem: updated testoom() and oom() funcs

the 'numa' parameter inside testoom() and 'mempolicy' inside oom() were useless, so removed them.

---
 testcases/kernel/mem/include/mem.h |  4 ++--
 testcases/kernel/mem/lib/mem.c     | 13 +++++--------
 testcases/kernel/mem/oom/oom01.c   |  6 +++---
 testcases/kernel/mem/oom/oom02.c   |  6 +++---
 testcases/kernel/mem/oom/oom03.c   | 10 +++++-----
 testcases/kernel/mem/oom/oom04.c   |  4 ++--
 6 files changed, 20 insertions(+), 23 deletions(-)
testcases/kernel/mem/include/mem.h +2 -2
index de51838..2fd675b 100644
@@ -27,8 +27,8 @@
 extern int ISNUMA;
 
 long overcommit;
-void oom(int testcase, int mempolicy, int lite);
-void testoom(int mempolicy, int lite, int numa);
+void oom(int testcase, int lite);
+void testoom(int mempolicy, int lite);
 
 /* KSM */
 
testcases/kernel/mem/lib/mem.c +5 -8
index e99dae7..438735a 100644
@@ -62,7 +62,7 @@ static void _test_alloc(int testcase, int lite)
 				return;
 }
 
-void oom(int testcase, int mempolicy, int lite)
+void oom(int testcase, int lite)
 {
 	pid_t pid;
 	int status;
@@ -92,7 +92,7 @@ void oom(int testcase, int mempolicy, int lite)
 	}
 }
 
-void testoom(int mempolicy, int lite, int numa)
+void testoom(int mempolicy, int lite)
 {
 #if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
 	&& HAVE_MPOL_CONSTANTS
@@ -133,20 +133,17 @@ void testoom(int mempolicy, int lite, int numa)
 	}
 #endif
 
-	if (numa && !mempolicy)
-		write_cpusets(get_a_numa_node(cleanup));
-
 	tst_resm(TINFO, "start normal OOM testing.");
-	oom(NORMAL, mempolicy, lite);
+	oom(NORMAL, lite);
 
 	tst_resm(TINFO, "start OOM testing for mlocked pages.");
-	oom(MLOCK, mempolicy, lite);
+	oom(MLOCK, lite);
 
 	if (access(PATH_KSM, F_OK) == -1)
 		tst_brkm(TCONF, NULL, "KSM configuration is not enabled");
 
 	tst_resm(TINFO, "start OOM testing for KSM pages.");
-	oom(KSM, mempolicy, lite);
+	oom(KSM, lite);
 }
 
 /* KSM */
testcases/kernel/mem/oom/oom01.c +3 -3
index 0401e31..43a5319 100644
@@ -61,13 +61,13 @@ int main(int argc, char *argv[])
 		tst_count = 0;
 
 		set_sys_tune("overcommit_memory", 2, 1);
-		oom(OVERCOMMIT, 0, 0);
+		oom(OVERCOMMIT, 0);
 
 		set_sys_tune("overcommit_memory", 0, 1);
-		oom(OVERCOMMIT, 0, 0);
+		oom(OVERCOMMIT, 0);
 
 		set_sys_tune("overcommit_memory", 1, 1);
-		testoom(0, 0, 0);
+		testoom(0, 0);
 	}
 	cleanup();
 	tst_exit();
testcases/kernel/mem/oom/oom02.c +3 -3
index 31ec73f..7566404 100644
@@ -65,13 +65,13 @@ int main(int argc, char *argv[])
 		tst_count = 0;
 
 		tst_resm(TINFO, "OOM on MPOL_BIND mempolicy...");
-		testoom(MPOL_BIND, 0, 1);
+		testoom(MPOL_BIND, 0);
 
 		tst_resm(TINFO, "OOM on MPOL_INTERLEAVE mempolicy...");
-		testoom(MPOL_INTERLEAVE, 0, 1);
+		testoom(MPOL_INTERLEAVE, 0);
 
 		tst_resm(TINFO, "OOM on MPOL_PREFERRED mempolicy...");
-		testoom(MPOL_PREFERRED, 0, 1);
+		testoom(MPOL_PREFERRED, 0);
 	}
 	cleanup();
 	tst_exit();
testcases/kernel/mem/oom/oom03.c +5 -5
index 4365c2b..86eff41 100644
@@ -68,7 +68,7 @@ int main(int argc, char *argv[])
 
 		snprintf(mem, BUFSIZ, "%ld", TESTMEM);
 		write_file(MEMCG_PATH_NEW "/memory.limit_in_bytes", mem);
-		testoom(0, 0, 0);
+		testoom(0, 0);
 
 		if (access(MEMCG_SW_LIMIT, F_OK) == -1) {
 			if (errno == ENOENT)
@@ -78,15 +78,15 @@ int main(int argc, char *argv[])
 				tst_brkm(TBROK | TERRNO, cleanup, "access");
 		} else {
 			write_file(MEMCG_SW_LIMIT, mem);
-			testoom(0, 1, 0);
+			testoom(0, 1);
 		}
 
 		/* OOM for MEMCG with mempolicy */
 		if (ISNUMA) {
 			tst_resm(TINFO, "OOM on MEMCG & mempolicy...");
-			testoom(MPOL_BIND, 0, 1);
-			testoom(MPOL_INTERLEAVE, 0, 1);
-			testoom(MPOL_PREFERRED, 0, 1);
+			testoom(MPOL_BIND, 0);
+			testoom(MPOL_INTERLEAVE, 0);
+			testoom(MPOL_PREFERRED, 0);
 		}
 	}
 	cleanup();
testcases/kernel/mem/oom/oom04.c +2 -2
index 6acc783..9423d60 100644
@@ -65,7 +65,7 @@ int main(int argc, char *argv[])
 		tst_count = 0;
 
 		tst_resm(TINFO, "OOM on CPUSET...");
-		testoom(0, 0, 0);
+		testoom(0, 0);
 
 		if (ISNUMA) {
 			/*
@@ -76,7 +76,7 @@ int main(int argc, char *argv[])
 			write_cpuset_files(CPATH_NEW,
 					   "memory_migrate", "1");
 			tst_resm(TINFO, "OOM on CPUSET with mem migrate:");
-			testoom(0, 0, 0);
+			testoom(0, 0);
 		}
 	}
 	cleanup();
Signature · 12 lines
1.7.11.7


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list
#5 lore raw

PATCH 5/5 mm/oom05: new testcase

added a new case to test OOM under the combination of MEMCG and CPUSET.

---
 runtest/mm                       |   1 +
 testcases/kernel/mem/oom/oom05.c | 151 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 152 insertions(+)
 create mode 100644 testcases/kernel/mem/oom/oom05.c
runtest/mm +1 -0
index a8bd605..56b83f8 100644
@@ -77,6 +77,7 @@ oom01 oom01
 oom02 oom02
 oom03 oom03
 oom04 oom04
+oom05 oom05
 
 swapping01 swapping01 -i 5
 
testcases/kernel/mem/oom/oom05.c new file +151 -0

151 lines not on this page · raw message

Signature · 12 lines
1.7.11.7


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list
#6 lore raw

Re: [LTP] [PATCH 3/5] mm/oom0[3|4]: added 'OOM for CPUSET' and updated 'OOM with MEMCG & numa'

In reply to Zhouping Liu

Hi!

Quoted 24 lines
 testcases/kernel/mem/include/mem.h |  2 ++
 testcases/kernel/mem/lib/mem.c     |  2 ++
 testcases/kernel/mem/oom/oom03.c   | 24 +++++++++++++++
 testcases/kernel/mem/oom/oom04.c   | 63 ++++++++++++++++----------------------
 4 files changed, 54 insertions(+), 37 deletions(-)
testcases/kernel/mem/include/mem.h +2 -0
index 1233493..de51838 100644
@@ -24,6 +24,8 @@
 #define MLOCK			3
 #define KSM			4
 
+extern int ISNUMA;
+
 long overcommit;
 void oom(int testcase, int mempolicy, int lite);
 void testoom(int mempolicy, int lite, int numa);
testcases/kernel/mem/lib/mem.c +0 -0
index a71bc90..e99dae7 100644

testcases/kernel/mem/lib/mem.c line 27

Quoted 4 lines
testcases/kernel/mem/lib/mem.c +1 -0
@@ -24,6 +24,8 @@
 #include "mem.h"
 #include "numa_helper.h"
 
+int ISNUMA = 0; /* mark a NUMA system */

So you have added variable to the library that is initialized in the test setup? That is just too messy :(.

testcases/kernel/mem/lib/mem.c

Quoted 9 lines
testcases/kernel/mem/lib/mem.c +9 -0
+	/* rough estimate a NUMA system through max_node */
+	if (numa_max_node() > 0) {
+		ISNUMA = 1;
+		/* For NUMA system, using the first node for cpuset.mems */
+		write_cpusets(get_a_numa_node(cleanup));
+	} else {
+		/* For nonNUMA system, using node0 for cpuset.mems */
+		write_cpusets(0);
+	}

Why couldn't we have a function is_numa() in the library that would do something like this snippet of code, i.e. return numa_max_node() > 0 (assuming that the code is needed in other test than this one.

Signature · 12 lines
Cyril Hrubis
[email protected]

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

A message that is not in the archive (sent off-list or not yet received): [email protected]

#8 lore raw

Re: [LTP] [PATCH 3/5] mm/oom0[3|4]: added 'OOM for CPUSET' and updated 'OOM with MEMCG & numa'

Hi!

Quoted 17 lines

We added numa_helper library to be able to get number of nodes, as well as list of nodes (with memory, cpu or both). numa_max_node() > 0 doesn't tell you how many nodes you have.

Here's sample use to get just node count:
----------------------------------------------------------------
#include <stdio.h>
#include "numa_helper.h"

const char *TCID="test";
int main()

{
        int num_nodes;
        int ret = get_allowed_nodes_arr(NH_MEMS | NH_CPUS, &num_nodes, NULL);
        printf("ret: %d, nodes:%d\n", ret, num_nodes);
        return 0;
}
Quoted 4 lines

----------------------------------------------------------------

We could add a simple function to numa_helper, but I'm not sure what it would return as default, some tests care about nodes with memory.

Maybe we misunderstand about what I see as a problem here. This patch adds integer variable to the lib/mem.c library and that variable is then only used within the tests. That just looks like wrong desing to me.

The code snippet "numa_max_node() > 0" was take from one of the tests that initializes the variable in question (the pattern seems to repeat in them). So I wasn't proposing any functional changes in the code just requesting cleaner desing.

Signature · 12 lines
Cyril Hrubis
[email protected]

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list
#9 lore raw

Re: [LTP] [PATCH 2/5] mm/oom02: modified 'OOM for NUMA' as 'OOM for mempolicy'

In reply to Zhouping Liu

testcases/kernel/mem/lib/mem.c void oom(int testcase, int mempolicy, int lite)

Quoted 6 lines · Zhouping Liu
testcases/kernel/mem/lib/mem.c +0 -0
index 29de64a..a71bc90 100644
@@ -64,32 +64,17 @@ void oom(int testcase, int mempolicy, int lite)

you've moved all mempolicy check stuff to testoom(), so you can completely remove this variable.

Quoted 70 lines
testcases/kernel/mem/lib/mem.c +32 -17
  {
  	pid_t pid;
  	int status;
-#if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
-	&& HAVE_MPOL_CONSTANTS
-	unsigned long nmask = 0;
-	unsigned int node;
-
-	if (mempolicy)
-		node = get_a_numa_node(cleanup);
-	nmask += 1 << node;
-#endif
 
  	switch (pid = fork()) {
  	case -1:
  		tst_brkm(TBROK | TERRNO, cleanup, "fork");
  	case 0:
-#if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
-	&& HAVE_MPOL_CONSTANTS
-		if (mempolicy)
-			if (set_mempolicy(MPOL_BIND, &nmask, MAXNODES) == -1)
-				tst_brkm(TBROK | TERRNO, cleanup,
-					 "set_mempolicy");
-#endif
  		_test_alloc(testcase, lite);
  		exit(0);
  	default:
  		break;
  	}
+
  	tst_resm(TINFO, "expected victim is %d.", pid);
  	if (waitpid(-1, &status, 0) == -1)
  		tst_brkm(TBROK | TERRNO, cleanup, "waitpid");
@@ -107,7 +92,44 @@ void oom(int testcase, int mempolicy, int lite)
 
  void testoom(int mempolicy, int lite, int numa)
  {
-	long nodes[MAXNODES];
+#if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
+	&& HAVE_MPOL_CONSTANTS
+	unsigned long nmask = 0;
+	unsigned int num_nodes, nodes[MAXNODES];
+	int ret;
+
+	if (mempolicy) {
+		ret = get_allowed_nodes_arr(NH_MEMS|NH_CPUS, &num_nodes, &nodes);
+		if (ret != 0)
+			tst_brkm(TBROK|TERRNO, cleanup,
+				 "get_allowed_nodes_arr");
+		if (num_nodes < 2) {
+			tst_resm(TINFO, "mempolicy need NUMA system support");
+			return;
+		}
+		switch(mempolicy) {
+		case MPOL_BIND:
+			/* bind the second node */
+			nmask = 1 << nodes[1];
+			break;
+		case MPOL_INTERLEAVE:
+		case MPOL_PREFERRED:
+			if (num_nodes == 2) {
+				tst_resm(TINFO, "The mempolicy need "
+					 "more than 2 numa nodes");
+				return;
+			} else {
+				/* Using the 2nd,3rd node */
+				nmask = (1 << nodes[1]) | (1 << nodes[2]);
+			}
+			break;

testcases/kernel/mem/lib/mem.c void oom(int testcase, int mempolicy, int lite) · line 135

Quoted 10 lines
testcases/kernel/mem/lib/mem.c +7 -0
+		default:
+			tst_brkm(TBROK|TERRNO, cleanup, "Bad mempolicy mode");
+		}
+		if (set_mempolicy(mempolicy, &nmask, MAXNODES) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup, "set_mempolicy");
+	}
+#endif
 
  	if (numa && !mempolicy)
  		write_cpusets(get_a_numa_node(cleanup));

The remaining concern to me is that, mempolicy set in parent process, can it be inherited by child? I see this patch changed the behavior that in new test, set_mempolicy happen in parent and oom happen in child.

Caspar

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

#10 lore raw

Re: [LTP] [PATCH 2/5] mm/oom02: modified 'OOM for NUMA' as 'OOM for mempolicy'

----- Original Message -----

Quoted 8 lines

From: "Caspar Zhang" <[email protected]>
To: "Zhouping Liu" <[email protected]>
Cc: "LTP List" <[email protected]>
Sent: Friday, March 15, 2013 11:09:33 AM
Subject: Re: [LTP] [PATCH 2/5] mm/oom02: modified 'OOM for NUMA' as 'OOM for mempolicy'

Quoted 1 line · Zhouping Liu
Quoted 9 lines

testcases/kernel/mem/lib/mem.c void oom(int testcase, int mempolicy, int lite)

Quoted 6 lines
testcases/kernel/mem/lib/mem.c +0 -0
index 29de64a..a71bc90 100644
@@ -64,32 +64,17 @@ void oom(int testcase, int mempolicy, int lite)

you've moved all mempolicy check stuff to testoom(), so you can completely remove this variable.

I'm not sure which variable you mean, pid and status variable? but they are needed.

Quoted 79 lines
Quoted 79 lines
testcases/kernel/mem/lib/mem.c +39 -17
  {
  	pid_t pid;
  	int status;
-#if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
-	&& HAVE_MPOL_CONSTANTS
-	unsigned long nmask = 0;
-	unsigned int node;
-
-	if (mempolicy)
-		node = get_a_numa_node(cleanup);
-	nmask += 1 << node;
-#endif
 
  	switch (pid = fork()) {
  	case -1:
  		tst_brkm(TBROK | TERRNO, cleanup, "fork");
  	case 0:
-#if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
-	&& HAVE_MPOL_CONSTANTS
-		if (mempolicy)
-			if (set_mempolicy(MPOL_BIND, &nmask, MAXNODES) == -1)
-				tst_brkm(TBROK | TERRNO, cleanup,
-					 "set_mempolicy");
-#endif
  		_test_alloc(testcase, lite);
  		exit(0);
  	default:
  		break;
  	}
+
  	tst_resm(TINFO, "expected victim is %d.", pid);
  	if (waitpid(-1, &status, 0) == -1)
  		tst_brkm(TBROK | TERRNO, cleanup, "waitpid");
@@ -107,7 +92,44 @@ void oom(int testcase, int mempolicy, int lite)
 
  void testoom(int mempolicy, int lite, int numa)
  {
-	long nodes[MAXNODES];
+#if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
+	&& HAVE_MPOL_CONSTANTS
+	unsigned long nmask = 0;
+	unsigned int num_nodes, nodes[MAXNODES];
+	int ret;
+
+	if (mempolicy) {
+		ret = get_allowed_nodes_arr(NH_MEMS|NH_CPUS, &num_nodes,
 &nodes);
+		if (ret != 0)
+			tst_brkm(TBROK|TERRNO, cleanup,
+				 "get_allowed_nodes_arr");
+		if (num_nodes < 2) {
+			tst_resm(TINFO, "mempolicy need NUMA system support");
+			return;
+		}
+		switch(mempolicy) {
+		case MPOL_BIND:
+			/* bind the second node */
+			nmask = 1 << nodes[1];
+			break;
+		case MPOL_INTERLEAVE:
+		case MPOL_PREFERRED:
+			if (num_nodes == 2) {
+				tst_resm(TINFO, "The mempolicy need "
+					 "more than 2 numa nodes");
+				return;
+			} else {
+				/* Using the 2nd,3rd node */
+				nmask = (1 << nodes[1]) | (1 << nodes[2]);
+			}
+			break;
+		default:
+			tst_brkm(TBROK|TERRNO, cleanup, "Bad mempolicy mode");
+		}
+		if (set_mempolicy(mempolicy, &nmask, MAXNODES) == -1)
+			tst_brkm(TBROK|TERRNO, cleanup, "set_mempolicy");
+	}
+#endif
 
Quoted 8 lines
Quoted 3 lines
testcases/kernel/mem/lib/mem.c +0 -0
  	if (numa && !mempolicy)
  		write_cpusets(get_a_numa_node(cleanup));

The remaining concern to me is that, mempolicy set in parent process, can it be inherited by child? I see this patch changed the behavior that
in new test, set_mempolicy happen in parent and oom happen in child.

The following words from the manual page can tell us the child inherit the father's mempolicy:

SET_MEMPOLICY(2)
...
The process memory policy is preserved across an execve(2), and is inherited by child processes created using fork(2) or clone(2).
...

Signature · 12 lines
Thanks,
Zhouping

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list
#11 lore raw

Re: [LTP] [PATCH 2/5] mm/oom02: modified 'OOM for NUMA' as 'OOM for mempolicy'

Quoted 4 lines · Zhouping Liu
Quoted 2 lines
Quoted 2 lines

you've moved all mempolicy check stuff to testoom(), so you can completely remove this variable.

I'm not sure which variable you mean, pid and status variable? but they are needed.

never mind, I see the 4/5 patch that removed this variable :)

Caspar

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

#12 lore raw

Re: [LTP] [PATCH 1/5] lib/mem: modified _gather_cpus() as _gather_node_cpus()

In reply to Zhouping Liu

Hi!

testcases/kernel/mem/lib/mem.c void ksm_usage(void) · line 484

Quoted 2 lines
testcases/kernel/mem/lib/mem.c +1 -1
-static void _gather_cpus(char *cpus, long nd)
+static void _gather_node_cpus(char *cpus, long nd)

I know that the function name starting with underscore was there allready but can we please get rid of them (idealy in separate patch either before or after this patch).

Quoted 15 lines

{

testcases/kernel/mem/lib/mem.c +5 -3
 	int ncpus = 0;
-	int i;
+	int fd, i;
+	long online;
 	char buf[BUFSIZ];
+	char path[BUFSIZ], path1[BUFSIZ];
 
 	while (path_exist(PATH_SYS_SYSTEM "/cpu/cpu%d", ncpus))
 		ncpus++;
 
-	for (i = 0; i < ncpus; i++)
-		if (path_exist(PATH_SYS_SYSTEM "/node/node%ld/cpu%d", nd, i)) {
+	for (i = 0; i < ncpus; i++) {
+		snprintf(path, BUFSIZ,

testcases/kernel/mem/lib/mem.c void ksm_usage(void) · line 506

Quoted 10 lines
testcases/kernel/mem/lib/mem.c +10 -0
+			 PATH_SYS_SYSTEM "/node/node%ld/cpu%d", nd, i);
+		if (path_exist(path, nd, i)) {
+			snprintf(path1, BUFSIZ, "%s/online", path);
+			/*
+			 * No cpu0/online knob, as it can't support to
+			 * on/offline cpu0, so if the 'nd' node contains
+			 * cpu0, it should skip to check cpu0/online's value.
+			 */
+			if (i == 0)
+				goto  next;

There are two spaces before the next.

testcases/kernel/mem/lib/mem.c void ksm_usage(void) · line 514

Quoted 8 lines
testcases/kernel/mem/lib/mem.c +8 -0
+			fd = open(path1, O_RDONLY);
+			if (fd == -1)
+				tst_brkm(TBROK|TERRNO, cleanup,
+					 "open %s", path1);
+			read_file(path1, buf);
+			online = SAFE_STRTOL(cleanup, buf, 0, 1);
+			if (online == 0)
+				continue;

This part can be done with SAFE_FILE_SCANF() see include/safe_file_ops.h

Quoted 17 lines
testcases/kernel/mem/lib/mem.c +3 -1
+next:
 			sprintf(buf, "%d,", i);
 			strcat(cpus, buf);
 		}
+	}
 	/* Remove the trailing comma. */
 	cpus[strlen(cpus) - 1] = '\0';
 }
@@ -563,7 +585,7 @@ void write_cpusets(long nd)
 	snprintf(buf, BUFSIZ, "%ld", nd);
 	write_cpuset_files(CPATH_NEW, "mems", buf);
 
-	_gather_cpus(cpus, nd);
+	_gather_node_cpus(cpus, nd);
 	write_cpuset_files(CPATH_NEW, "cpus", cpus);
 
 	snprintf(buf, BUFSIZ, "%d", getpid());
Signature · 12 lines
Cyril Hrubis
[email protected]

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list