Hi,
v2 -> v3: modified variables' type, updated overcommit_memory_test function,
updated the comment lines.
please review it again, any comments are welcome.
There are two tunables overcommit_memory and overcommit_ratio under
/proc/sys/vm/, which can control memory overcommitment.
The overcommit_memory tunable contains a flag that enables memory
overcommitment, it has three values:
- When this flag is 0, the kernel attempts to estimate the amount
of free memory left when userspace requests more memory.
- When this flag is 1, the kernel pretends there is always enough
memory until it actually runs out.
- When this flag is 2, the kernel uses a "never overcommit" policy
that attempts to prevent any overcommit of memory.
The overcommit_ratio tunable defines the amount by which the kernel
overextends its memory resources in the event that overcommit_memory
is set to the value of 2. The value in this file represents a
percentage added to the amount of actual RAM in a system when
considering whether to grant a particular memory request.
The general formula for this tunable is:
CommitLimit = SwapTotal + MemTotal * overcommit_ratio
CommitLimit, SwapTotal and MemTotal can read from /proc/meminfo.
The program is designed to test the two tunables:
When overcommit_memory = 0, allocatable memory can't overextends
the amount of free memory. I choose the three cases:
a. less than free_total: free_total / 2, alloc should pass.
b. equal to free_total: free_total, alloc should pass.
c. greater than free_total: free_total * 2, alloc should fail.
When overcommit_memory = 1, it can alloc enough much memory, I
choose the three cases:
a. less than sum_total: sum_total / 2, alloc should pass.
b. equal to sum_total: sum_total, alloc should pass.
c. greater than sum_total: sum_total * 2, alloc should pass.
*note: sum_total = SwapTotal + MemTotal
When overcommit_memory = 2,
allocatable memory = CommitLimit - Committed_As
I define it as commit_left, also I choose three cases:
a. less than commit_left: commit_left / 2, alloc should pass.
b. greater than commit_left: commit_left * 2, alloc should fail.
c. overcommit limit: CommitLimit, alloc should fail.
*note: CommitLimit is the current overcommit limit.
Committed_AS is the amount of memory that system has used.
why I din't choose 'equal to commit_left' as a case, because in
this case, the result is not fixed after I tested some times.
References:
- Documentation/sysctl/vm.txt
- Documentation/vm/overcommit-accounting
Signed-off-by: Zhouping Liu <z...@redhat.com>
---
runtest/mm | 7 +
testcases/kernel/mem/tunable/Makefile | 42 ++++
testcases/kernel/mem/tunable/overcommit_memory.c | 282 ++++++++++++++++++++++
3 files changed, 331 insertions(+), 0 deletions(-)
create mode 100644 testcases/kernel/mem/tunable/Makefile
create mode 100644 testcases/kernel/mem/tunable/overcommit_memory.c
--
Thanks,
Zhouping Liu
From c27ff0aec57cf015856473cd22b835e06660b23d Mon Sep 17 00:00:00 2001
From: Zhouping Liu <z...@redhat.com>
Date: Tue, 30 Aug 2011 19:54:53 +0800
Subject: [PATCH 2/2] mem/tunable: new testcase of memory overcommit
There are two tunables overcommit_memory and overcommit_ratio under
/proc/sys/vm/, which can control memory overcommitment.
The overcommit_memory contains a flag that enables memory
overcommitment, it has three values:
- When this flag is 0, the kernel attempts to estimate the amount
of free memory left when userspace requests more memory.
- When this flag is 1, the kernel pretends there is always enough
memory until it actually runs out.
- When this flag is 2, the kernel uses a "never overcommit" policy
that attempts to prevent any overcommit of memory.
The overcommit_ratio tunable defines the amount by which the kernel
overextends its memory resources in the event that overcommit_memory
is set to the value of 2. The value in this file represents a
percentage added to the amount of actual RAM in a system when
considering whether to grant a particular memory request.
The general formula for this tunable is:
CommitLimit = SwapTotal + MemTotal * overcommit_ratio
CommitLimit, SwapTotal and MemTotal can read from /proc/meminfo.
The program is designed to test the two tunables:
When overcommit_memory = 0, allocatable memory can't overextends
the amount of free memory. I choose the three cases:
a. less than free_total: free_total / 2, alloc should pass.
b. equal to free_total: free_total, alloc should pass.
c. greater than free_total: free_total * 2, alloc should fail.
When overcommit_memory = 1, it can alloc enough much memory, I
choose the three cases:
a. less than sum_total: sum_total / 2, alloc should pass.
b. equal to sum_total: sum_total, alloc should pass.
c. greater than sum_total: sum_total * 2, alloc should pass.
*note: sum_total = SwapTotal + MemTotal
When overcommit_memory = 2,
allocatable memory = CommitLimit - Committed_As
I define it as commit_left, also I choose three cases:
a. less than commit_left: commit_left / 2, alloc should pass.
b. greater than commit_left: commit_left * 2, alloc should fail.
c. overcommit limit: CommitLimit, alloc should fail.
*note: CommitLimit is the current overcommit limit.
Committed_AS is the amount of memory that system has used.
why I din't choose 'equal to commit_left' as a case, because in
this case, the result is not fixed after I tested some times.
References:
- Documentation/sysctl/vm.txt
- Documentation/vm/overcommit-accounting
Signed-off-by: Zhouping Liu <z...@redhat.com>
---
runtest/mm | 7 +
testcases/kernel/mem/tunable/Makefile | 42 ++++
testcases/kernel/mem/tunable/overcommit_memory.c | 282 ++++++++++++++++++++++
3 files changed, 331 insertions(+), 0 deletions(-)
create mode 100644 testcases/kernel/mem/tunable/Makefile
create mode 100644 testcases/kernel/mem/tunable/overcommit_memory.c
diff --git a/runtest/mm b/runtest/mm
index 615f1f1..fb71189 100644
--- a/runtest/mm
+++ b/runtest/mm
@@ -82,3 +82,10 @@ thp01 thp01 -I 120
vma01 vma01
vma02 vma02
+
+overcommit_memory overcommit_memory
+overcommit_memory_1 overcommit_memory -R 0
+overcommit_memory_2 overcommit_memory -R 30
+overcommit_memory_3 overcommit_memory -R 80
+overcommit_memory_4 overcommit_memory -R 100
+overcommit_memory_5 overcommit_memory -R 200
diff --git a/testcases/kernel/mem/tunable/Makefile b/testcases/kernel/mem/tunable/Makefile
new file mode 100644
index 0000000..8ab52da
--- /dev/null
+++ b/testcases/kernel/mem/tunable/Makefile
@@ -0,0 +1,42 @@
+#
+# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+top_srcdir ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+LDLIBS += $(NUMA_LIBS) -lmem
+LIBDIR := ../lib
+LIB := $(LIBDIR)/libmem.a
+FILTER_OUT_DIRS := $(LIBDIR)
+LDFLAGS += -L$(LIBDIR)
+
+$(LIBDIR):
+ mkdir -p "$@"
+
+$(LIB): $(LIBDIR)
+ $(MAKE) -C $^ -f "$(abs_srcdir)/$^/Makefile" all
+
+MAKE_DEPS := $(LIB)
+
+trunk-clean:: | lib-clean
+
+lib-clean:: $(LIBDIR)
+ $(MAKE) -C $^ -f "$(abs_srcdir)/$^/Makefile" clean
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/mem/tunable/overcommit_memory.c b/testcases/kernel/mem/tunable/overcommit_memory.c
new file mode 100644
index 0000000..6c51d1c
--- /dev/null
+++ b/testcases/kernel/mem/tunable/overcommit_memory.c
@@ -0,0 +1,282 @@
+/*
+ * Description:
+ *
+ * There are two tunables overcommit_memory and overcommit_ratio under
+ * /proc/sys/vm/, which can control memory overcommitment.
+ *
+ * The overcommit_memory contains a flag that enables memory
+ * overcommitment, it has three values:
+ * - When this flag is 0, the kernel attempts to estimate the amount
+ * of free memory left when userspace requests more memory.
+ * - When this flag is 1, the kernel pretends there is always enough
+ * memory until it actually runs out.
+ * - When this flag is 2, the kernel uses a "never overcommit" policy
+ * that attempts to prevent any overcommit of memory.
+ *
+ * The overcommit_ratio tunable defines the amount by which the kernel
+ * overextends its memory resources in the event that overcommit_memory
+ * is set to the value of 2. The value in this file represents a
+ * percentage added to the amount of actual RAM in a system when
+ * considering whether to grant a particular memory request.
+ * The general formula for this tunable is:
+ * CommitLimit = SwapTotal + MemTotal * overcommit_ratio
+ * CommitLimit, SwapTotal and MemTotal can read from /proc/meminfo.
+ *
+ * The program is designed to test the two tunables:
+ *
+ * When overcommit_memory = 0, allocatable memory can't overextends
+ * the amount of free memory. I choose the three cases:
+ * a. less than free_total: free_total / 2, alloc should pass.
+ * b. equal to free_total: free_total, alloc should pass.
+ * c. greater than free_total: free_total * 2, alloc should fail.
+ *
+ * When overcommit_memory = 1, it can alloc enough much memory, I
+ * choose the three cases:
+ * a. less than sum_total: sum_total / 2, alloc should pass
+ * b. equal to sum_total: sum_total, alloc should pass
+ * c. greater than sum_total: sum_total * 2, alloc should pass
+ * *note: sum_total = SwapTotal + MemTotal
+ *
+ * When overcommit_memory = 2,
+ * allocatable memory = CommitLimit - Committed_AS
+ * I define it as commit_left, also I choose three cases:
+ * a. less than commit_left: commit_left / 2, alloc should pass
+ * b. greater than commit_left: commit_left * 2, alloc should fail
+ * c. overcommit limit: CommitLimit, alloc should fail
+ * *note: CommitLimit is the current overcommit limit.
+ * Committed_AS is the amount of memory that system has used.
+ * why I din't choose 'equal to commit_left' as a case, because in
+ * this case, the result is not fixed after I tested some times.
+ *
+ * References:
+ * - Documentation/sysctl/vm.txt
+ * - Documentation/vm/overcommit-accounting
+ *
+ * ********************************************************************
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <linux/mman.h>
+#include "test.h"
+#include "usctest.h"
+#include "../include/mem.h"
+
+#define FILE_OVER_MEM PATH_SYSVM "overcommit_memory"
+#define FILE_OVER_RATIO PATH_SYSVM "overcommit_ratio"
+#define DEFAULT_OVER_RATIO 50LL
+#define EXPECT_PASS 0
+#define EXPECT_FAIL 1
+
+char *TCID = "overcommit_memory";
+static long long old_overcommit_memory;
+static long long old_overcommit_ratio;
+static long long overcommit_ratio;
+static long long sum_total;
+static long long free_total;
+static long long commit_limit;
+static long long commit_left;
+static int R_flag;
+static char *R_opt;
+option_t options[] = {
+ { "R:", &R_flag, &R_opt },
+ { NULL, NULL, NULL }
+};
+
+
+static void overcommit_memory_test(void);
+static int heavy_malloc(long long size);
+static void alloc_and_check(long long size, int expect_result);
+static void usage(void);
+static void update_mem(void);
+
+int main(int argc, char *argv[])
+{
+ char *msg;
+ int lc;
+
+ overcommit_ratio = DEFAULT_OVER_RATIO;
+
+ msg = parse_opts(argc, argv, options, &usage);
+ if (msg != NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ if (R_flag) {
+ overcommit_ratio = atoll(R_opt);
+ if (overcommit_ratio < 0) {
+ tst_brkm(TBROK, NULL, "-R option is required a"
+ "Non-negative");
+ tst_exit();
+ }
+ }
+
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+ Tst_count = 0;
+
+ overcommit_memory_test();
+ }
+
+ cleanup();
+
+ tst_exit();
+}
+
+void setup(void)
+{
+ long long mem_total, swap_total;
+
+ tst_require_root(NULL);
+
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+ if (access(FILE_OVER_MEM, F_OK) != 0 ||
+ access(FILE_OVER_RATIO, F_OK) != 0)
+ tst_brkm(TCONF, NULL, "The system "
+ "can't support to test %s", TCID);
+
+ old_overcommit_memory = get_sys_tune(FILE_OVER_MEM);
+ old_overcommit_ratio = get_sys_tune(FILE_OVER_RATIO);
+
+ set_sys_tune(FILE_OVER_RATIO, overcommit_ratio);
+ check_sys_tune(FILE_OVER_RATIO, overcommit_ratio);
+
+ mem_total = read_meminfo("MemTotal:");
+ tst_resm(TINFO, "MemTotal is %lld kB", mem_total);
+ swap_total = read_meminfo("SwapTotal:");
+ tst_resm(TINFO, "SwapTotal is %lld kB", swap_total);
+ sum_total = mem_total + swap_total;
+
+ commit_limit = read_meminfo("CommitLimit:");
+ tst_resm(TINFO, "CommitLimit is %lld kB", commit_limit);
+}
+
+void cleanup(void)
+{
+ set_sys_tune(FILE_OVER_MEM, old_overcommit_memory);
+ set_sys_tune(FILE_OVER_RATIO, old_overcommit_ratio);
+
+ TEST_CLEANUP;
+}
+
+static void usage(void)
+{
+ printf(" -R n Percentage of overcommitting memory\n");
+}
+
+static void overcommit_memory_test(void)
+{
+ tst_resm(TINFO, "starting test overcommit_memory = 0");
+ set_sys_tune(FILE_OVER_MEM, OVERCOMMIT_GUESS);
+ check_sys_tune(FILE_OVER_MEM, OVERCOMMIT_GUESS);
+
+ update_mem();
+ alloc_and_check(free_total / 2, EXPECT_PASS);
+ update_mem();
+ alloc_and_check(free_total, EXPECT_PASS);
+ update_mem();
+ alloc_and_check(free_total * 2, EXPECT_FAIL);
+
+ tst_resm(TINFO, "starting test overcommit_memory = 1");
+ set_sys_tune(FILE_OVER_MEM, OVERCOMMIT_ALWAYS);
+ check_sys_tune(FILE_OVER_MEM, OVERCOMMIT_ALWAYS);
+
+ alloc_and_check(sum_total / 2, EXPECT_PASS);
+ alloc_and_check(sum_total, EXPECT_PASS);
+ alloc_and_check(sum_total * 2, EXPECT_PASS);
+
+ tst_resm(TINFO, "starting test overcommit_memory = 2");
+ set_sys_tune(FILE_OVER_MEM, OVERCOMMIT_NEVER);
+ check_sys_tune(FILE_OVER_MEM, OVERCOMMIT_NEVER);
+
+ update_mem();
+ alloc_and_check(commit_left / 2, EXPECT_PASS);
+ update_mem();
+ alloc_and_check(commit_left * 2, EXPECT_FAIL);
+ alloc_and_check(commit_limit, EXPECT_FAIL);
+}
+
+static int heavy_malloc(long long size)
+{
+ char *p;
+
+ p = (char *)malloc(size * KB);
+ if (p != NULL) {
+ tst_resm(TINFO, "malloc %lld kB successfully", size);
+ free(p);
+ return 0;
+ } else {
+ tst_resm(TINFO, "malloc %lld kB failed", size);
+ return 1;
+ }
+}
+
+static void alloc_and_check(long long size, int expect_result)
+{
+ int result;
+
+ tst_resm(TINFO, "try to alloc memory = %lld kB", size);
+ result = heavy_malloc(size);
+
+ switch (expect_result) {
+ case EXPECT_PASS:
+ if (result == 0)
+ tst_resm(TPASS, "alloc passed as expected");
+ else
+ tst_resm(TFAIL, "alloc failed, expected to pass");
+ break;
+ case EXPECT_FAIL:
+ if (result != 0)
+ tst_resm(TPASS, "alloc failed as expected");
+ else
+ tst_resm(TFAIL, "alloc passed, expected to fail");
+ break;
+ default:
+ tst_brkm(TBROK, cleanup, "Invaild numbler parameter: %d",
+ expect_result);
+ }
+}
+
+static void update_mem(void)
+{
+ long long mem_free, swap_free;
+ long long committed;
+
+ mem_free = read_meminfo("MemFree:");
+ swap_free = read_meminfo("SwapFree:");
+ free_total = mem_free + swap_free;
+
+ committed = read_meminfo("Committed_AS:");
+ commit_left = commit_limit - committed;
+ if (commit_left < 0)
+ tst_brkm(TBROK, cleanup, "unexpected error:"
+ "CommitLimit > Committed_AS");
+}
--
1.7.6
------------------------------------------------------------------------------
Special Offer -- Download ArcSight Logger for FREE!
Finally, a world-class log management solution at an even better
price-free! And you'll get a free "Love Thy Logs" t-shirt when you
download Logger. Secure your free ArcSight Logger TODAY!
http://p.sf.net/sfu/arcsisghtdev2dev
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list