Hi, Garrett,
Please review the new test case.

 * The program is designed to test /proc/sys/vm/nr_overcommit_hugepages
 * tunable. /proc/sys/vm/nr_overcommit_hugepages specifies how large 
 * the pool of huge pages can grow, if more huge pages than 
 * /proc/sys/vm/nr_hugepages are requested by applications.  
 * Writing any non-zero value into this file indicates that the hugetlb 
 * subsystem is allowed to try to obtain that number of "surplus" huge 
 * pages from the kernel's normal page pool, when the persistent huge 
 * page pool is exhausted. As these surplus huge pages become unused, 
 * they are freed back to the kernel's normal page pool. When applicatons
 * alloc more huge pages, it will overcommit the hugepage pool,  we can 
 * confirmed the correction by /proc/meminfo: HugePages_Surp.

Signed-off-by: Zhouping Liu <z...@redhat.com>
---
 .../kernel/mem/vmtunable/nr_overcommit_hugepages.c |  300 ++++++++++++++++++++
 1 files changed, 300 insertions(+), 0 deletions(-)
 create mode 100644 testcases/kernel/mem/vmtunable/nr_overcommit_hugepages.c

diff --git a/testcases/kernel/mem/vmtunable/nr_overcommit_hugepages.c 
b/testcases/kernel/mem/vmtunable/nr_overcommit_hugepages.c
new file mode 100644
index 0000000..00d4983
--- /dev/null
+++ b/testcases/kernel/mem/vmtunable/nr_overcommit_hugepages.c
@@ -0,0 +1,300 @@
+/*
+ * vm tunable test
+ *
+ * ********************************************************************
+ * 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.
+ *
+ * ********************************************************************
+ *
+ * File Name: nr_overcommit_hugepage.c
+ * Author: Zhouping Liu <z...@redhat.com>
+ * Description:  
+ * The program is designed to test /proc/sys/vm/nr_overcommit_hugepages
+ * tunable. /proc/sys/vm/nr_overcommit_hugepages specifies how large 
+ * the pool of huge pages can grow, if more huge pages than 
+ * /proc/sys/vm/nr_hugepages are requested by applications.  
+ * Writing any non-zero value into this file indicates that the hugetlb 
+ * subsystem is allowed to try to obtain that number of "surplus" huge 
+ * pages from the kernel's normal page pool, when the persistent huge 
+ * page pool is exhausted. As these surplus huge pages become unused, 
+ * they are freed back to the kernel's normal page pool. When applicatons
+ * alloc more huge pages, it will overcommit the hugepage pool,  we can 
+ * confirmed the correction by /proc/meminfo: HugePages_Surp.
+ * 
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+
+#include "test.h"
+#include "usctest.h"
+
+char *TCID = "nr_overcommit_hugepages"; 
+int TST_TOTAL = 1;
+
+#define NUM 50UL /* the amount of hugepages try to mmap */
+#define HUGEPAGES 30 /* set /proc/sys/vm/nr_hugepages */
+#define OVER_HUGEPAGES 30 /* set /proc/sys/vm/nr_overcommit_hugepages */
+#define BUFFER_SIZE 256 
+#define FILE_NAME "/mnt/hugepagefile"
+#define PROTECTION (PROT_READ | PROT_WRITE) /* mmap mode */
+
+/* Only ia64 requires this */
+#ifdef __ia64__
+#define ADDR (void *)(0x8000000000000000UL)
+#define FLAGS (MAP_SHARED | MAP_FIXED)
+#else
+#define ADDR (void *)(0x0UL)
+#define FLAGS (MAP_SHARED)
+#endif
+
+/* Check whether there're the two tunable or not */
+int check_system();
+
+/* We're not sure one hugepag size is 2048kb or not, we can confirm
+ * it by catting /proc/meminfo: Hugepagesize
+ */
+unsigned long get_one_hugepage_size();
+
+/* set hugepages */
+int set_hugepages(int nr_hugepages, int nr_overcommit_hugepages);
+
+/* get the total of hugepages and surplus hugepages */ 
+int get_hugepages(int *nr_hugepages, int *nr_overcommit_hugepages);
+
+/* try to alloc overcommit hugepage */
+int test_overcommit_hugepages();
+
+/* do some clean after test */
+void cleanup();
+
+int old_hugepages;
+int old_overcommit; /* save the original data */
+
+int main(int argc, char *argv[])
+{
+       int lc = 0; /* loop counter */
+       char *msg;
+       
+       /* if check_system() return zero, the system can't support the testing 
*/
+       if (check_system() == 0) {
+               tst_resm(TFAIL, "Can't test nr_hugepages and \
+                               nr_overcommit_hugepages,no such file");
+               tst_exit();
+       }
+
+       if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL) {
+               tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR -%s", msg);
+       }
+       get_hugepages(&old_hugepages, &old_overcommit);
+       tst_resm(TINFO, "old nr_hugepages value is %d", old_hugepages);
+       tst_resm(TINFO, "old nr_overcommit hugepages is %d", old_overcommit);
+       
+       for (lc = 0; TEST_LOOPING(lc); lc++) {
+               set_hugepages(HUGEPAGES, OVER_HUGEPAGES);
+               if (test_overcommit_hugepages() == 0) {
+                       set_hugepages(old_hugepages, old_overcommit);
+                       tst_resm(TPASS, "succeeded to overcommit hugepages");
+               } else {
+                       tst_resm(TFAIL, "FAIL mapping!");
+               }
+               cleanup();
+       }
+
+       tst_exit();
+       return 0;
+}
+
+/* try to overcommit hugepages */
+int test_overcommit_hugepages()
+{
+       char *addr;
+       int fd;
+       int hugepages = 0;
+       int overcommit = 0;
+       unsigned long i;
+       unsigned long length = 0;
+       unsigned long one_hugepage_size = 0;
+
+       /* mount hugetlbfs */
+       if (system("mount -t hugetlbfs nodev /mnt") != 0) {
+               tst_brkm(TBROK, cleanup, "Can't mount hugetlbfs");
+       }
+
+       fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
+       if (fd < 0) {
+               tst_brkm(TBROK, cleanup, "OPEN File %s error", FILE_NAME);
+               tst_exit();
+       }
+       
+       one_hugepage_size = get_one_hugepage_size();
+       length = NUM * one_hugepage_size;
+       addr = (char *)mmap(ADDR, length, PROTECTION, FLAGS, fd, 0);
+       if (addr == MAP_FAILED) {
+               tst_resm(TFAIL, "mmap() Failed on %s, errno=%d : %s", \
+                               FILE_NAME, errno, strerror(errno));
+               munmap(addr, length);
+               close(fd);
+               unlink(FILE_NAME);
+               cleanup();
+               tst_exit();
+       }
+
+       tst_resm(TINFO, "Returned address is %p", addr);
+       tst_resm(TINFO, "First hex is %x", *((unsigned int *)addr));
+       for (i = 0; i < length; i++) {
+               *(addr + i) = (char)i;
+       }
+
+       sleep(1);
+       /* get the hugepages and surplus hugepages after mmap successfully */
+       get_hugepages(&hugepages, &overcommit);
+       
+       munmap(addr, length);
+       close(fd);
+       unlink(FILE_NAME);
+       tst_resm(TINFO, "the current hugepages is %d and overcommit is %d ", 
hugepages, overcommit);
+       
+       /* if everything is okay, overcommit should equal (NUM - HUGEPAGES) */
+       if(hugepages == NUM && overcommit == (NUM - HUGEPAGES)) {
+               return 0;
+       } else {
+               return -1;
+       }
+}
+
+unsigned long get_one_hugepage_size()
+{
+       FILE *f;
+       int retcode = 0;
+       char buff[BUFFER_SIZE];
+       unsigned long one_hugepage_size = 0;
+
+       f = fopen("/proc/meminfo", "r");
+       if (f == NULL) {
+               tst_brkm(TFAIL, cleanup, "Please run the test using root 
user.");
+       }
+       while(fgets(buff,BUFFER_SIZE, f) != NULL) {
+               if((retcode = sscanf(buff, "Hugepagesize: %lu kB",
+                       &one_hugepage_size)) == 1)
+                       break;
+       }
+       tst_resm(TINFO, "one hugepagesize is %lu", one_hugepage_size);
+       fclose(f);
+       
+       if(one_hugepage_size == 0) {
+               tst_brkm(TFAIL, cleanup, "Can't read out hugepage size");
+       }
+
+       return one_hugepage_size * 1024UL;
+}
+
+/* get nr_hugepages and nr_overcommit_hugepages values */
+int get_hugepages(int *nr_hugepages, int *nr_overcommit_hugepages) 
+{
+       FILE *f;
+       int flag = 0;
+       int retcode = 0;
+       char buff[BUFFER_SIZE];
+
+       f = fopen("/proc/meminfo", "r");
+       if (f == NULL) {
+               tst_brkm(TFAIL, cleanup, "Please run the test using root 
user.");
+       }
+       while(fgets(buff,BUFFER_SIZE, f) != NULL && flag < 2) {
+               if((retcode = sscanf(buff, "HugePages_Total: %d ",
+                       nr_hugepages)) == 1)
+                       flag++;
+               if((retcode = sscanf(buff, "HugePages_Surp: %d ", 
+                       nr_overcommit_hugepages)) == 1) 
+                       flag++;
+       }
+
+       if (flag != 2) {
+               fclose(f); 
+               tst_brkm(TFAIL, cleanup, "Failed reading size of huge page.");
+       }
+       fclose(f);
+
+       return 0;
+}
+
+/* set nr_hugepages and nr_overcommit_hugepages values */
+int set_hugepages(int nr_hugepages, int nr_overcommit_hugepages)
+{
+       FILE *f1, *f2;
+
+       f1 = fopen("/proc/sys/vm/nr_hugepages", "w");
+       if (f1 == NULL) {
+               tst_brkm(TFAIL, tst_exit, "No permission, using root user");
+       }
+
+       f2 = fopen("/proc/sys/vm/nr_overcommit_hugepages", "w");
+       if (f2 == NULL) {
+               tst_brkm(TFAIL, tst_exit, "No permission, using root user");
+       }
+
+       /* write nr_hugepages to /proc/sys/vm/nr_hugepages and 
+        * nr_overcommit_hugepages to /proc/sys/vm/nr_overcommit_hugepages
+        */
+       if (fprintf(f1, "%d", nr_hugepages) == 0) {
+               tst_brkm(TFAIL, cleanup, "write date error to nr_hugepages");
+       }
+       if (fprintf(f2, "%d", nr_overcommit_hugepages) ==0 ) {
+               tst_brkm(TFAIL, cleanup, "write date error to 
nr_overcommit_hugepages");
+       }
+       fclose(f1);
+       fclose(f2);
+       
+       return 0;
+}
+
+int check_system()
+{
+       int flag1 = -1;
+       int flag2 = -1;
+
+       flag1 = access("/proc/sys/vm/nr_hugepages", F_OK);
+       flag2 = access("/proc/sys/vm/nr_overcommit_hugepages", F_OK);
+
+       if (flag1 == 0 && flag2 == 0) {
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
+void cleanup()
+{
+       set_hugepages(old_hugepages, old_overcommit);
+       tst_exit();
+
+       return;
+}
+
-- 
1.7.3.4


------------------------------------------------------------------------------
Enable your software for Intel(R) Active Management Technology to meet the
growing manageability and security demands of your customers. Businesses
are taking advantage of Intel(R) vPro (TM) technology - will your software 
be a part of the solution? Download the Intel(R) Manageability Checker 
today! http://p.sf.net/sfu/intel-dev2devmar
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to