1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * This is a reproducer from mainline commit 3f08c3bdfSopenharmony_ci * 9d8cebd4bcd7c3878462fdfda34bbcdeb4df7ef4: 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * "Strangely, current mbind() doesn't merge vma with neighbor vma 6f08c3bdfSopenharmony_ci * although it's possible. Unfortunately, many vma can reduce 7f08c3bdfSopenharmony_ci * performance..." 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * Copyright (C) 2010 Red Hat, Inc. 10f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or 11f08c3bdfSopenharmony_ci * modify it under the terms of version 2 of the GNU General Public 12f08c3bdfSopenharmony_ci * License as published by the Free Software Foundation. 13f08c3bdfSopenharmony_ci * 14f08c3bdfSopenharmony_ci * This program is distributed in the hope that it would be useful, 15f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 16f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17f08c3bdfSopenharmony_ci * 18f08c3bdfSopenharmony_ci * Further, this software is distributed without any warranty that it 19f08c3bdfSopenharmony_ci * is free of the rightful claim of any third person regarding 20f08c3bdfSopenharmony_ci * infringement or the like. Any license provided herein, whether 21f08c3bdfSopenharmony_ci * implied or otherwise, applies only to this software file. Patent 22f08c3bdfSopenharmony_ci * licenses, if any, provided herein do not apply to combinations of 23f08c3bdfSopenharmony_ci * this program with other software, or any other product whatsoever. 24f08c3bdfSopenharmony_ci * 25f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 26f08c3bdfSopenharmony_ci * along with this program; if not, write the Free Software 27f08c3bdfSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 28f08c3bdfSopenharmony_ci * 02110-1301, USA. 29f08c3bdfSopenharmony_ci */ 30f08c3bdfSopenharmony_ci#include "config.h" 31f08c3bdfSopenharmony_ci#include <sys/types.h> 32f08c3bdfSopenharmony_ci#include <sys/mman.h> 33f08c3bdfSopenharmony_ci#include <errno.h> 34f08c3bdfSopenharmony_ci#if HAVE_NUMA_H 35f08c3bdfSopenharmony_ci#include <numa.h> 36f08c3bdfSopenharmony_ci#endif 37f08c3bdfSopenharmony_ci#if HAVE_NUMAIF_H 38f08c3bdfSopenharmony_ci#include <numaif.h> 39f08c3bdfSopenharmony_ci#endif 40f08c3bdfSopenharmony_ci#include <stdio.h> 41f08c3bdfSopenharmony_ci#include <stdlib.h> 42f08c3bdfSopenharmony_ci#include <string.h> 43f08c3bdfSopenharmony_ci#include <unistd.h> 44f08c3bdfSopenharmony_ci#include <limits.h> 45f08c3bdfSopenharmony_ci#include "test.h" 46f08c3bdfSopenharmony_ci#include "safe_macros.h" 47f08c3bdfSopenharmony_ci#include "numa_helper.h" 48f08c3bdfSopenharmony_ci 49f08c3bdfSopenharmony_cichar *TCID = "vma02"; 50f08c3bdfSopenharmony_ciint TST_TOTAL = 1; 51f08c3bdfSopenharmony_ci 52f08c3bdfSopenharmony_ci#ifdef HAVE_NUMA_V2 53f08c3bdfSopenharmony_ci 54f08c3bdfSopenharmony_cistatic unsigned long pagesize; 55f08c3bdfSopenharmony_cistatic int opt_node; 56f08c3bdfSopenharmony_cistatic char *opt_nodestr; 57f08c3bdfSopenharmony_cistatic option_t options[] = { 58f08c3bdfSopenharmony_ci {"n:", &opt_node, &opt_nodestr}, 59f08c3bdfSopenharmony_ci {NULL, NULL, NULL} 60f08c3bdfSopenharmony_ci}; 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_cistatic void usage(void); 63f08c3bdfSopenharmony_ci 64f08c3bdfSopenharmony_ciint main(int argc, char **argv) 65f08c3bdfSopenharmony_ci{ 66f08c3bdfSopenharmony_ci FILE *fp; 67f08c3bdfSopenharmony_ci void *addr, *start, *end, *lastend; 68f08c3bdfSopenharmony_ci int node, err, lc; 69f08c3bdfSopenharmony_ci char buf[BUFSIZ]; 70f08c3bdfSopenharmony_ci struct bitmask *nmask = numa_allocate_nodemask(); 71f08c3bdfSopenharmony_ci 72f08c3bdfSopenharmony_ci pagesize = getpagesize(); 73f08c3bdfSopenharmony_ci tst_parse_opts(argc, argv, options, usage); 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_ci if (opt_node) { 76f08c3bdfSopenharmony_ci node = SAFE_STRTOL(NULL, opt_nodestr, 1, LONG_MAX); 77f08c3bdfSopenharmony_ci } else { 78f08c3bdfSopenharmony_ci err = get_allowed_nodes(NH_MEMS | NH_MEMS, 1, &node); 79f08c3bdfSopenharmony_ci if (err == -3) 80f08c3bdfSopenharmony_ci tst_brkm(TCONF, NULL, "requires at least one node."); 81f08c3bdfSopenharmony_ci else if (err < 0) 82f08c3bdfSopenharmony_ci tst_brkm(TBROK | TERRNO, NULL, "get_allowed_nodes"); 83f08c3bdfSopenharmony_ci } 84f08c3bdfSopenharmony_ci numa_bitmask_setbit(nmask, node); 85f08c3bdfSopenharmony_ci 86f08c3bdfSopenharmony_ci for (lc = 0; TEST_LOOPING(lc); lc++) { 87f08c3bdfSopenharmony_ci tst_count = 0; 88f08c3bdfSopenharmony_ci addr = mmap(NULL, pagesize * 3, PROT_WRITE, 89f08c3bdfSopenharmony_ci MAP_ANON | MAP_PRIVATE, 0, 0); 90f08c3bdfSopenharmony_ci if (addr == MAP_FAILED) 91f08c3bdfSopenharmony_ci tst_brkm(TBROK | TERRNO, NULL, "mmap"); 92f08c3bdfSopenharmony_ci 93f08c3bdfSopenharmony_ci tst_resm(TINFO, "pid = %d addr = %p", getpid(), addr); 94f08c3bdfSopenharmony_ci /* make page populate */ 95f08c3bdfSopenharmony_ci memset(addr, 0, pagesize * 3); 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci /* first mbind */ 98f08c3bdfSopenharmony_ci err = mbind(addr + pagesize, pagesize, MPOL_BIND, nmask->maskp, 99f08c3bdfSopenharmony_ci nmask->size, MPOL_MF_MOVE_ALL); 100f08c3bdfSopenharmony_ci if (err != 0) { 101f08c3bdfSopenharmony_ci if (errno != ENOSYS) 102f08c3bdfSopenharmony_ci tst_brkm(TBROK | TERRNO, NULL, "mbind1"); 103f08c3bdfSopenharmony_ci else 104f08c3bdfSopenharmony_ci tst_brkm(TCONF, NULL, 105f08c3bdfSopenharmony_ci "mbind syscall not implemented on this system."); 106f08c3bdfSopenharmony_ci } 107f08c3bdfSopenharmony_ci 108f08c3bdfSopenharmony_ci /* second mbind */ 109f08c3bdfSopenharmony_ci err = mbind(addr, pagesize * 3, MPOL_DEFAULT, NULL, 0, 0); 110f08c3bdfSopenharmony_ci if (err != 0) 111f08c3bdfSopenharmony_ci tst_brkm(TBROK | TERRNO, NULL, "mbind2"); 112f08c3bdfSopenharmony_ci 113f08c3bdfSopenharmony_ci /* /proc/self/maps in the form of 114f08c3bdfSopenharmony_ci "00400000-00406000 r-xp 00000000". */ 115f08c3bdfSopenharmony_ci fp = fopen("/proc/self/maps", "r"); 116f08c3bdfSopenharmony_ci if (fp == NULL) 117f08c3bdfSopenharmony_ci tst_brkm(TBROK | TERRNO, NULL, "fopen"); 118f08c3bdfSopenharmony_ci 119f08c3bdfSopenharmony_ci while (fgets(buf, BUFSIZ, fp) != NULL) { 120f08c3bdfSopenharmony_ci if (sscanf(buf, "%p-%p ", &start, &end) != 2) 121f08c3bdfSopenharmony_ci continue; 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_ci if (start == addr) { 124f08c3bdfSopenharmony_ci tst_resm(TINFO, "start = %p, end = %p", 125f08c3bdfSopenharmony_ci start, end); 126f08c3bdfSopenharmony_ci if (end == addr + pagesize * 3) { 127f08c3bdfSopenharmony_ci tst_resm(TPASS, "only 1 VMA."); 128f08c3bdfSopenharmony_ci break; 129f08c3bdfSopenharmony_ci } 130f08c3bdfSopenharmony_ci 131f08c3bdfSopenharmony_ci lastend = end; 132f08c3bdfSopenharmony_ci while (fgets(buf, BUFSIZ, fp) != NULL) { 133f08c3bdfSopenharmony_ci /* No more VMAs, break */ 134f08c3bdfSopenharmony_ci if (sscanf(buf, "%p-%p ", &start, 135f08c3bdfSopenharmony_ci &end) != 2) 136f08c3bdfSopenharmony_ci break; 137f08c3bdfSopenharmony_ci tst_resm(TINFO, "start = %p, end = %p", 138f08c3bdfSopenharmony_ci start, end); 139f08c3bdfSopenharmony_ci 140f08c3bdfSopenharmony_ci /* more VMAs found */ 141f08c3bdfSopenharmony_ci if (start == lastend) 142f08c3bdfSopenharmony_ci lastend = end; 143f08c3bdfSopenharmony_ci if (end == addr + pagesize * 3) { 144f08c3bdfSopenharmony_ci tst_resm(TFAIL, 145f08c3bdfSopenharmony_ci ">1 unmerged VMAs."); 146f08c3bdfSopenharmony_ci break; 147f08c3bdfSopenharmony_ci } 148f08c3bdfSopenharmony_ci } 149f08c3bdfSopenharmony_ci if (end != addr + pagesize * 3) 150f08c3bdfSopenharmony_ci tst_resm(TFAIL, "no matched VMAs."); 151f08c3bdfSopenharmony_ci break; 152f08c3bdfSopenharmony_ci } 153f08c3bdfSopenharmony_ci } 154f08c3bdfSopenharmony_ci fclose(fp); 155f08c3bdfSopenharmony_ci if (munmap(addr, pagesize * 3) == -1) 156f08c3bdfSopenharmony_ci tst_brkm(TWARN | TERRNO, NULL, "munmap"); 157f08c3bdfSopenharmony_ci } 158f08c3bdfSopenharmony_ci tst_exit(); 159f08c3bdfSopenharmony_ci} 160f08c3bdfSopenharmony_ci 161f08c3bdfSopenharmony_civoid usage(void) 162f08c3bdfSopenharmony_ci{ 163f08c3bdfSopenharmony_ci printf(" -n Number of NUMA nodes\n"); 164f08c3bdfSopenharmony_ci} 165f08c3bdfSopenharmony_ci 166f08c3bdfSopenharmony_ci#else 167f08c3bdfSopenharmony_ciint main(void) 168f08c3bdfSopenharmony_ci{ 169f08c3bdfSopenharmony_ci tst_brkm(TCONF, NULL, NUMA_ERROR_MSG); 170f08c3bdfSopenharmony_ci} 171f08c3bdfSopenharmony_ci#endif 172