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