12e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang/*
22e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * Copyright (C) 2012 Linux Test Project
32e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang *
42e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * This program is free software; you can redistribute it and/or
52e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * modify it under the terms of version 2 of the GNU General Public
62e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * License as published by the Free Software Foundation.
72e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang *
82e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * This program is distributed in the hope that it would be useful,
92e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * but WITHOUT ANY WARRANTY; without even the implied warranty of
102e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
112e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang *
122e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * Further, this software is distributed without any warranty that it
132e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * is free of the rightful claim of any third person regarding
142e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * infringement or the like.  Any license provided herein, whether
152e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * implied or otherwise, applies only to this software file.  Patent
162e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * licenses, if any, provided herein do not apply to combinations of
172e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * this program with other software, or any other product whatsoever.
182e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang *
192e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * You should have received a copy of the GNU General Public License
202e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * along with this program; if not, write the Free Software
212e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
222e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * 02110-1301, USA.
232e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang */
242e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang/*
252e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * There are several corner cases (documented in mm/mmap.c) for mbind
262e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * vma merge issue, which makes commit 8aacc9f550 slightly incorrect.
272e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * KOSAKI Motohiro made a patch for it (commit e26a511) and composed
282e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * a reproducer containing these corner cases. Now I port it to LTP.
292e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang *
302e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * Author: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
312e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * Ported-to-LTP-by: Caspar Zhang <caspar@casparzhang.com>
322e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang */
332e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
342e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#include "config.h"
352e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#include <sys/types.h>
362e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#include <sys/mman.h>
3779667facbd7a489bad97dcda1e2d319ee2a7a70eCaspar Zhang#include <errno.h>
382e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#if HAVE_NUMA_H
392e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#include <numa.h>
402e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#endif
412e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#if HAVE_NUMAIF_H
422e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#include <numaif.h>
432e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#endif
442e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#include <stdio.h>
452e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#include <stdlib.h>
462e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#include <string.h>
472e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#include <unistd.h>
482e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#include "test.h"
492e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#include "safe_macros.h"
50a98ac196630f2bfdb90ce077b8d2a6ea209415aaCaspar Zhang#include "numa_helper.h"
512e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
522e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangchar *TCID = "vma04";
532e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangint TST_TOTAL = 5;
542e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
552e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
562e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	&& HAVE_MPOL_CONSTANTS
572e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#if defined(LIBNUMA_API_VERSION) && LIBNUMA_API_VERSION == 2
582e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic unsigned long pagesize;
592e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic int opt_node;
602e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic char *opt_nodestr;
612e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic char retbuf[BUFSIZ];
622e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void *mmap_addr;
632e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic struct bitmask *nmask;
642e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
652e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic option_t options[] = {
66354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{"n:", &opt_node, &opt_nodestr},
67354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{NULL, NULL, NULL}
682e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang};
692e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
702e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void init(void);
712e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void fin(void);
722e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void mem_bind(int index, int len);
732e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void mem_interleave(int index, int len);
742e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void mem_unbind(int index, int len);
752e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void assertion(char *expected, char *value, char *name);
762e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void get_vmas(char *retbuf, void *addr_s, void *addr_e);
772e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void case4(void);
782e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void case5(void);
792e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void case6(void);
802e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void case7(void);
812e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void case8(void);
822e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void setup(void);
832e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void cleanup(void);
842e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void usage(void);
852e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
862e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangint main(int argc, char **argv)
872e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
88a98ac196630f2bfdb90ce077b8d2a6ea209415aaCaspar Zhang	int lc, node, err;
892e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
90d6d11d08678aac1ed2c370ea8e42e5f45aea07beCyril Hrubis	tst_parse_opts(argc, argv, options, usage);
912e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
922e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	nmask = numa_allocate_nodemask();
932e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	if (opt_node) {
942e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		node = SAFE_STRTOL(NULL, opt_nodestr, 1, LONG_MAX);
952e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	} else {
96354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		err = get_allowed_nodes(NH_MEMS | NH_MEMS, 1, &node);
97a98ac196630f2bfdb90ce077b8d2a6ea209415aaCaspar Zhang		if (err == -3)
98a98ac196630f2bfdb90ce077b8d2a6ea209415aaCaspar Zhang			tst_brkm(TCONF, NULL, "requires at least one node.");
99a98ac196630f2bfdb90ce077b8d2a6ea209415aaCaspar Zhang		else if (err < 0)
100354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			tst_brkm(TBROK | TERRNO, NULL, "get_allowed_nodes");
1012e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	}
102a98ac196630f2bfdb90ce077b8d2a6ea209415aaCaspar Zhang	numa_bitmask_setbit(nmask, node);
1032e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
1042e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	setup();
1052e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
1062e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	for (lc = 0; TEST_LOOPING(lc); lc++) {
107d59a659cd639ca2780b00049d102acd2a783d585Caspar Zhang		tst_count = 0;
1082e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
1092e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		case4();
1102e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		case5();
1112e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		case6();
1122e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		case7();
1132e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		case8();
1142e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	}
1152e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
1162e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	cleanup();
1172e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	tst_exit();
1182e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
1192e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
1202e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang/*
1212e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang *  BBBBBB
1222e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * AAAAAAAA
1232e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang */
1242e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void init(void)
1252e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
1262e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	void *addr;
1272e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
128354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	addr = SAFE_MMAP(cleanup, NULL, pagesize * 8, PROT_NONE,
129354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			 MAP_ANON | MAP_PRIVATE, 0, 0);
130354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	SAFE_MMAP(cleanup, addr + pagesize, pagesize * 6,
131354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		  PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, 0,
132354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		  0);
1332e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
1342e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	mmap_addr = addr + pagesize;
135354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	memset(mmap_addr, 0, pagesize * 6);
1362e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
1372e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
1382e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void fin(void)
1392e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
1402e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	void *addr;
1412e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
1422e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	addr = mmap_addr - pagesize;
143354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	SAFE_MUNMAP(cleanup, addr, pagesize * 8);
1442e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
1452e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	memset(retbuf, 0, sizeof(retbuf));
1462e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
1472e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
1482e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void mem_bind(int index, int len)
1492e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
150354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (mbind(mmap_addr + pagesize * index, pagesize * len,
151354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		  MPOL_BIND, nmask->maskp, nmask->size, 0) != 0) {
1522e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		if (errno != ENOSYS)
153354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			tst_brkm(TBROK | TERRNO, cleanup, "mbind: bind");
1542e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		else
1552e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang			tst_brkm(TCONF, cleanup,
156354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 "mbind syscall not implemented "
157354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 "on this system.");
1582e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	}
1592e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
1602e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
1612e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void mem_interleave(int index, int len)
1622e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
163354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (mbind(mmap_addr + pagesize * index, pagesize * len,
164354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		  MPOL_INTERLEAVE, nmask->maskp, nmask->size, 0) != 0) {
1652e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		if (errno != ENOSYS)
166354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			tst_brkm(TBROK | TERRNO, cleanup, "mbind: interleave");
1672e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		else
1682e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang			tst_brkm(TCONF, cleanup,
169354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 "mbind syscall not implemented "
170354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 "on this system.");
1712e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	}
1722e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
1732e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
1742e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void mem_unbind(int index, int len)
1752e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
176354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (mbind(mmap_addr + pagesize * index, pagesize * len,
177354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		  MPOL_DEFAULT, NULL, 0, 0) != 0) {
1782e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		if (errno != ENOSYS)
179354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			tst_brkm(TBROK | TERRNO, cleanup, "mbind: unbind");
1802e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		else
1812e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang			tst_brkm(TCONF, cleanup,
182354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 "mbind syscall not implemented "
183354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				 "on this system.");
1842e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	}
1852e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
1862e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
1872e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void assertion(char *expected, char *value, char *name)
1882e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
1892e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	if (strcmp(expected, value) == 0)
1902e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		tst_resm(TPASS, "%s: passed.", name);
1912e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	else
1922e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		tst_resm(TFAIL, "%s: failed. expect '%s', actual '%s'",
193354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			 name, expected, value);
1942e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
1952e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
1962e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void get_vmas(char *retbuf, void *addr_s, void *addr_e)
1972e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
1982e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	FILE *fp;
1992e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	void *s, *t;
2002e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	char buf[BUFSIZ], tmpstr[BUFSIZ];
201354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int flag;
2022e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
2032e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	retbuf[0] = '\0';
2042e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	flag = 0;
2052e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	fp = fopen("/proc/self/maps", "r");
2062e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	if (fp == NULL)
207354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		tst_brkm(TBROK | TERRNO, cleanup, "fopen");
2082e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	while (fgets(buf, BUFSIZ, fp) != NULL) {
2092e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		if (sscanf(buf, "%p-%p ", &s, &t) != 2)
2102e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang			continue;
2112e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		if (addr_s <= s && s < addr_e) {
2122e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang			if (!flag) {
213354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				sprintf(tmpstr, "%ld", (t - s) / pagesize);
2142e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang				flag = 1;
2152e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang			} else {
216354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				sprintf(tmpstr, ",%ld", (t - s) / pagesize);
2172e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang			}
2182e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang			strncat(retbuf, tmpstr, 32);
2192e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang		}
2202e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	}
2212e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	fclose(fp);
2222e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
2232e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
2242e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang/*
2252e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang *   AAAA
2262e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * PPPPPPNNNNNN
2272e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * might become
2282e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * PPNNNNNNNNNN
2292e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * case 4 below
2302e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang */
2312e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void case4(void)
2322e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
2332e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	init();
2342e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	mem_bind(0, 4);
2352e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	mem_unbind(2, 2);
236354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	get_vmas(retbuf, mmap_addr, mmap_addr + pagesize * 6);
2372e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	assertion("2,4", retbuf, "case4");
2382e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	fin();
2392e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
2402e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
2412e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang/*
2422e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang *       AAAA
2432e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * PPPPPPNNNNNN
2442e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * might become
2452e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * PPPPPPPPPPNN
2462e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * case 5 below
2472e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang */
2482e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void case5(void)
2492e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
2502e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	init();
2512e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	mem_bind(0, 2);
2522e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	mem_bind(2, 2);
253354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	get_vmas(retbuf, mmap_addr, mmap_addr + pagesize * 6);
2542e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	assertion("4,2", retbuf, "case5");
2552e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	fin();
2562e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
2572e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
2582e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang/*
2592e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang *     AAAA
2602e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * PPPPNNNNXXXX
2612e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * might become
2622e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * PPPPPPPPPPPP 6
2632e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang */
2642e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void case6(void)
2652e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
2662e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	init();
2672e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	mem_bind(0, 2);
2682e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	mem_bind(4, 2);
2692e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	mem_bind(2, 2);
270354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	get_vmas(retbuf, mmap_addr, mmap_addr + pagesize * 6);
2712e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	assertion("6", retbuf, "case6");
2722e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	fin();
2732e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
2742e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
2752e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang/*
2762e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang *     AAAA
2772e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * PPPPNNNNXXXX
2782e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * might become
2792e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * PPPPPPPPXXXX 7
2802e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang */
2812e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void case7(void)
2822e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
2832e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	init();
2842e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	mem_bind(0, 2);
2852e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	mem_interleave(4, 2);
2862e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	mem_bind(2, 2);
287354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	get_vmas(retbuf, mmap_addr, mmap_addr + pagesize * 6);
2882e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	assertion("4,2", retbuf, "case7");
2892e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	fin();
2902e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
2912e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
2922e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang/*
2932e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang *     AAAA
2942e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * PPPPNNNNXXXX
2952e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * might become
2962e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang * PPPPNNNNNNNN 8
2972e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang */
2982e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void case8(void)
2992e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
3002e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	init();
3012e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	mem_bind(0, 2);
3022e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	mem_interleave(4, 2);
3032e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	mem_interleave(2, 2);
304354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	get_vmas(retbuf, mmap_addr, mmap_addr + pagesize * 6);
3052e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	assertion("2,4", retbuf, "case8");
3062e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	fin();
3072e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
3082e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
3092e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void setup(void)
3102e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
3112e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	tst_sig(FORK, DEF_HANDLER, cleanup);
3122e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
3132e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	TEST_PAUSE;
3142e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
3152e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	pagesize = getpagesize();
3162e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
3172e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
3182e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void cleanup(void)
3192e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
3202e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
3212e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
3222e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangstatic void usage(void)
3232e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
3242e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	printf("  -n      Number of NUMA nodes\n");
3252e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
3262e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang
3272e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#else /* libnuma v1 */
3282e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangint main(void)
3292e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
3302e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	tst_brkm(TCONF, NULL, "XXX: test is only supported on libnuma v2.");
3312e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
3322e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#endif
3332e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#else /* no NUMA */
3342e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhangint main(void)
3352e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang{
3362e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang	tst_brkm(TCONF, NULL, "no NUMA development packages installed.");
3372e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang}
3382e2f72af82b25ea5604e670ee381d999fcfee5b2Caspar Zhang#endif
339