vma01 - test not merging a VMA which cloned from parent process
This program is used for testing the following upstream commit:
965f55dea0e331152fa53941a51e4e16f9f06fae
The cloned VMA shares the anon_vma lock with the parent process's
VMA. If we do the merge, more vmas (even the new range is only
for current process) use the perent process's anon_vma lock. This
introduces scalability issues. find_mergeable_anon_vma() already
considers this case.
This test program clones VMA and checks /proc/$pid/maps file, on
an unpatched kernel, there is a single 6*ps VMA for the child
like this:
7fee32989000-7fee3298f000 -w-p 00000000 00:00 0
On a patched kernel, there are two 3*ps VMAs like this:
7f55bbd47000-7f55bbd4a000 -w-p 00000000 00:00 0
7f55bbd4a000-7f55bbd4d000 -w-p 00000000 00:00 0
Signed-off-by: Caspar Zhang <[email protected]>
---
runtest/mm | 2 +
testcases/kernel/mem/vma/Makefile | 24 ++++++
testcases/kernel/mem/vma/vma01.c | 163 +++++++++++++++++++++++++++++++++++++
3 files changed, 189 insertions(+), 0 deletions(-)
create mode 100644 testcases/kernel/mem/vma/Makefile
create mode 100644 testcases/kernel/mem/vma/vma01.c
diff --git a/runtest/mm b/runtest/mm
index df7d0cb..5b08d15 100644
--- a/runtest/mm
+++ b/runtest/mm
@@ -80,3 +80,5 @@ oom03 oom03
oom04 oom04
thp01 thp01 -I 120
+
+vma01 vma01
diff --git a/testcases/kernel/mem/vma/Makefile b/testcases/kernel/mem/vma/Makefile
new file mode 100644
index 0000000..6b347c4
--- /dev/null
+++ b/testcases/kernel/mem/vma/Makefile
@@ -0,0 +1,24 @@
+#
+# Copyright (C) 2011 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+
+top_srcdir ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/mem/vma/vma01.c b/testcases/kernel/mem/vma/vma01.c
new file mode 100644
index 0000000..edcd95c
--- /dev/null
+++ b/testcases/kernel/mem/vma/vma01.c
@@ -0,0 +1,163 @@
+/*
+ * vma01 - test not merging a VMA which cloned from parent process
+ *
+ * This program is used for testing the following upstream commit:
+ * 965f55dea0e331152fa53941a51e4e16f9f06fae
+ *
+ * The cloned VMA shares the anon_vma lock with the parent process's
+ * VMA. If we do the merge, more vmas (even the new range is only
+ * for current process) use the perent process's anon_vma lock. This
+ * introduces scalability issues. find_mergeable_anon_vma() already
+ * considers this case.
+ *
+ * This test program clones VMA and checks /proc/$pid/maps file, on
+ * an unpatched kernel, there is a single 6*ps VMA for the child
+ * like this:
+ *
+ * 7fee32989000-7fee3298f000 -w-p 00000000 00:00 0
+ *
+ * On a patched kernel, there are two 3*ps VMAs like this:
+ *
+ * 7f55bbd47000-7f55bbd4a000 -w-p 00000000 00:00 0
+ * 7f55bbd4a000-7f55bbd4d000 -w-p 00000000 00:00 0
+ *
+ * Copyright (C) 2011 Red Hat, Inc.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it
+ * is free of the rightful claim of any third person regarding
+ * infringement or the like. Any license provided herein, whether
+ * implied or otherwise, applies only to this software file. Patent
+ * licenses, if any, provided herein do not apply to combinations of
+ * this program with other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "vma01";
+int TST_TOTAL = 1;
+
+static void check_vma(void);
+static void *get_end_addr(void *addr_s, char *mapfile);
+static void setup(void);
+static void cleanup(void);
+
+static unsigned long ps;
+
+int main(int argc, char **argv)
+{
+ char *msg;
+ int lc;
+
+ msg = parse_opts(argc, argv, NULL, NULL);
+ if (msg != NULL)
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+ ps = sysconf(_SC_PAGE_SIZE);
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ Tst_count = 0;
+
+ check_vma();
+ }
+ cleanup();
+ tst_exit();
+}
+
+static void check_vma(void)
+{
+ pid_t pid;
+ void *t, *u, *v, *x, *y;
+ char mapfile[BUFSIZ];
+
+ t = mmap(NULL, 3*ps, PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
+ if (t == MAP_FAILED)
+ tst_brkm(TBROK|TERRNO, cleanup, "mmap");
+ tst_resm(TINFO, "t = %p", t);
+ memset(t, 1, ps);
+ v = mmap(NULL, 3*ps, PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
+ if (v == MAP_FAILED)
+ tst_brkm(TBROK|TERRNO, cleanup, "mmap");
+ tst_resm(TINFO, "v = %p", v);
+ memset(v, 2, ps);
+
+ switch (pid = fork()) {
+ case -1:
+ tst_brkm(TBROK|TERRNO, cleanup, "fork");
+ case 0:
+ sprintf(mapfile, "/proc/%u/maps", getpid());
+ memset(t, 2, ps);
+ u = mmap(t + 3*ps, 3*ps, PROT_WRITE,
+ MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
+ if (u == MAP_FAILED)
+ tst_brkm(TBROK|TERRNO, NULL, "mmap");
+ tst_resm(TINFO, "u = %p", u);
+ memset(u, 2, 4096);
+ x = get_end_addr(u, mapfile);
+ if (x == u + 6*ps)
+ tst_resm(TFAIL, "A single 6*ps VMA found.");
+ else if (x == u + 3*ps) {
+ y = get_end_addr(x, mapfile);
+ if (y == x + 3*ps)
+ tst_resm(TPASS, "two 3*ps VMAs found.");
+ } else
+ tst_brkm(TBROK, cleanup, "unexpected VMA found.");
+ exit(0);
+ default:
+ break;
+ }
+
+}
+
+static void *get_end_addr(void *addr_s, char *mapfile)
+{
+ FILE *fp;
+ void *s, *t;
+ char buf[BUFSIZ];
+
+ fp = fopen(mapfile, "r+");
+ if (fp == NULL)
+ tst_brkm(TBROK|TERRNO, cleanup, "fopen");
+ while (fgets(buf, BUFSIZ, fp) != NULL) {
+ if (sscanf(buf, "%p-%p ", &s, &t) != 2)
+ continue;
+ if (addr_s == s) {
+ tst_resm(TINFO, "s = %p, t = %p", s, t);
+ fclose(fp);
+ return t;
+ }
+ }
+ fclose(fp);
+ tst_brkm(TBROK, cleanup, "no matched s = %p found.", addr_s);
+}
+
+static void setup(void)
+{
+ tst_sig(FORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+}
+
+static void cleanup(void)
+{
+ TEST_CLEANUP;
+}
------------------------------------------------------------------------------
Got Input? Slashdot Needs You.
Take our quick survey online. Come on, we don't ask for help often.
Plus, you'll get a chance to win $100 to spend on ThinkGeek.
http://p.sf.net/sfu/slashdot-survey
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list