[Fwd: Re: [LTP]: Test Case Design for move_pages()]]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Christoph/Tony/Helge,

Vijay has recently submitted the following testcases for move_pages()
syscall. Can you kindly review the test code and provide your feedback.
We would be integrating this code into LTP soon.

Regards--
Subrata




From: Vijay Kumar <vijaykumar@xxxxxxxxxxxx>

Hi Subrata,

I have updated the patch, I have also written the rest of ther
testcases. It seems Suzuki is busy, I am yet to get review comments
from Suzuki.

The following fixes have been made to original patch.

  * Not using linux/mempolicy.h now, using numaif.h instead. This was
    causing a build break for older kernels.

  * Using a wrapper script to invoke the test case programs. The
    wrapper script checks if the test case program exists before
    invoking it.

  * Using semaphores to execute parent and child test processes in
    lock step.

The following test cases are not implemented

  * Test case for errno = EACCES - not sure how to generate this
    error. Tried with set_mempolicy() but does not seem to work.

  * Test case for status[x] = -EFAULT - generating a invalid address
    that works for all configurations seems to be hard.

  * Test case for status[x] = -EBUSY - not sure how to generate this
    error.

The following test case has been implemented but fails. I guess it's a
bug in the implemenation or a bug in the man page.

  * Test case for status[x] = -EPERM - man page says this occurs for
    mlocked pages, but this does not seem to be the case.

Signed-off-by: Vijay Kumar <vijaykumar@xxxxxxxxxxxx>

Index: ltp-mod/testcases/kernel/syscalls/move_pages/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/Makefile	2008-06-29 22:04:41.000000000 +0530
@@ -0,0 +1,46 @@
+#
+#  Copyright (c) International Business Machines  Corp., 2001
+#
+#  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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+
+CFLAGS += -I../../../../include -Wall
+LDLIBS += -L../../../../lib -lltp -lnuma -lrt
+
+ifeq ($(HAS_NUMA),yes)
+SRCS    = $(wildcard *.c)
+TARGETS = $(patsubst %.c, %, $(wildcard *[0-9].c))
+endif
+
+all: $(TARGETS)
+
+move_pages_support.o: move_pages_support.h move_pages_support.c
+
+$(TARGETS): move_pages_support.o
+
+install: move_page03.mode move_page12.mode
+	@set -e; for i in $(TARGETS); do ln -f $$i ../../../bin/$$i ; done
+	chmod 755 move_pages.sh; cp move_pages.sh ../../../bin/.
+
+clean:
+	rm -f $(TARGETS)
+
+move_page03.mode:
+	@/bin/sh ./move_pages03.mode.sh
+
+move_page12.mode:
+	@/bin/sh ./move_pages12.mode.sh
+
+.PHONY: move_pages03.mode
\ No newline at end of file
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages01.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages01.c	2008-06-29 09:56:02.000000000 +0530
@@ -0,0 +1,151 @@
+/*
+ *   Copyright (c) 2008 Vijay Kumar B. <vijaykumar@xxxxxxxxxxxx>
+ *
+ *   Based on testcases/kernel/syscalls/waitpid/waitpid01.c
+ *   Original copyright message:
+ *
+ *   Copyright (c) International Business Machines  Corp., 2001
+ *
+ *   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
+ */
+
+/*
+ * NAME
+ *	move_pages01.c
+ *
+ * DESCRIPTION
+ *      Test retrieval of NUMA node
+ *
+ * ALGORITHM
+ *      1. Allocate pages in NUMA nodes A and B.
+ *      2. Use move_pages() to retrieve the NUMA node of the pages.
+ *      3. Check if the NUMA nodes reported are correct.
+ *
+ * USAGE:  <for command-line>
+ *      move_pages01 [-c n] [-i n] [-I x] [-P x] [-t]
+ *      where,  -c n : Run n copies concurrently.
+ *              -i n : Execute test n times.
+ *              -I x : Execute test for x seconds.
+ *              -P x : Pause for x seconds between iterations.
+ *              -t   : Turn on syscall timing.
+ *
+ * History
+ *	05/2008 Vijay Kumar
+ *		Initial Version.
+ *
+ * Restrictions
+ *	None
+ */
+
+#include <sys/signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <numa.h>
+
+#include <test.h>
+#include <usctest.h>
+
+#include "move_pages_support.h"
+
+#define TEST_PAGES 2
+#define TEST_NODES TEST_PAGES
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "move_pages01";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+int main(int argc, char **argv)
+{
+	int lc;				/* loop counter */
+	char *msg;			/* message returned from parse_opts */
+
+	/* parse standard options */
+	msg = parse_opts(argc, argv, (option_t *) NULL, NULL);
+	if (msg != NULL) {
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+		tst_exit();
+		/* NOTREACHED */
+	}
+
+	setup();
+
+	/* check for looping state if -i option is given */
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		void *pages[TEST_PAGES] = { 0 };
+		int status[TEST_PAGES];
+		int ret;
+
+		/* reset Tst_count in case we are looping */
+		Tst_count = 0;
+
+		ret = alloc_pages_linear(pages, TEST_PAGES);
+		if (ret == -1)
+			continue;
+
+		ret = numa_move_pages(0, TEST_PAGES, pages, NULL, status, 0);
+		TEST_ERRNO = errno;
+		if (ret != 0) {
+			tst_resm(TFAIL, "retrieving NUMA nodes failed");
+			free_pages(pages, TEST_PAGES);
+			continue;
+		}
+
+		verify_pages_linear(status, TEST_PAGES);
+
+		free_pages(pages, TEST_PAGES);
+	}
+
+	cleanup();
+	/* NOT REACHED */
+
+	return 0;
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+	/* capture signals */
+	tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+	check_config(TEST_NODES);
+	/* Pause if that option was specified
+	 * TEST_PAUSE contains the code to fork the test with the -c option.
+	 */
+	TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test
+ */
+void
+cleanup(void)
+{
+	/*
+	 * print timing stats if that option was specified.
+	 * print errno log if that option was specified.
+	 */
+	TEST_CLEANUP;
+
+	/* exit with return code appropriate for results */
+	tst_exit();
+	/*NOTREACHED*/
+}
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages02.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages02.c	2008-06-29 09:56:02.000000000 +0530
@@ -0,0 +1,160 @@
+/*
+ *   Copyright (c) 2008 Vijay Kumar B. <vijaykumar@xxxxxxxxxxxx>
+ *
+ *   Based on testcases/kernel/syscalls/waitpid/waitpid01.c
+ *   Original copyright message:
+ *
+ *   Copyright (c) International Business Machines  Corp., 2001
+ *
+ *   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
+ */
+
+/*
+ * NAME
+ *	move_pages02.c
+ *
+ * DESCRIPTION
+ *      Test movement of pages mapped by a process.
+ *
+ * ALGORITHM
+ *      1. Allocate pages in NUMA node A.
+ *      2. Use move_pages() to move the pages to NUMA node B.
+ *      3. Retrieve the NUMA nodes of the moved pages.
+ *      4. Check if all pages are in node B.
+ *
+ * USAGE:  <for command-line>
+ *      move_pages02 [-c n] [-i n] [-I x] [-P x] [-t]
+ *      where,  -c n : Run n copies concurrently.
+ *              -i n : Execute test n times.
+ *              -I x : Execute test for x seconds.
+ *              -P x : Pause for x seconds between iterations.
+ *              -t   : Turn on syscall timing.
+ *
+ * History
+ *	05/2008 Vijay Kumar
+ *		Initial Version.
+ *
+ * Restrictions
+ *	None
+ */
+
+#include <sys/signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <numa.h>
+
+#include <test.h>
+#include <usctest.h>
+
+#include "move_pages_support.h"
+
+#define TEST_PAGES 2
+#define TEST_NODES 2
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "move_pages02";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+int main(int argc, char **argv)
+{
+	unsigned int i;
+	int lc;				/* loop counter */
+	char *msg;			/* message returned from parse_opts */
+	unsigned int from_node = 0;
+	unsigned int to_node = 1;
+
+	/* parse standard options */
+	msg = parse_opts(argc, argv, (option_t *) NULL, NULL);
+	if (msg != NULL) {
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+		tst_exit();
+		/* NOTREACHED */
+	}
+
+	setup();
+
+	/* check for looping state if -i option is given */
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		void *pages[TEST_PAGES] = { 0 };
+		int nodes[TEST_PAGES];
+		int status[TEST_PAGES];
+		int ret;
+
+		/* reset Tst_count in case we are looping */
+		Tst_count = 0;
+
+		ret = alloc_pages_on_node(pages, TEST_PAGES, from_node);
+		if (ret == -1)
+			continue;
+
+		for (i = 0; i < TEST_PAGES; i++)
+			nodes[i] = to_node;
+
+		ret = numa_move_pages(0, TEST_PAGES, pages, nodes, status, MPOL_MF_MOVE);
+		TEST_ERRNO = errno;
+		if (ret != 0) {
+			tst_resm(TFAIL, "retrieving NUMA nodes failed");
+			free_pages(pages, TEST_PAGES);
+			continue;
+		}
+
+		verify_pages_on_node(status, TEST_PAGES, to_node);
+
+		free_pages(pages, TEST_PAGES);
+	}
+
+	cleanup();
+	/* NOT REACHED */
+
+	return 0;
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+	/* capture signals */
+	tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+	check_config(TEST_NODES);
+
+	/* Pause if that option was specified
+	 * TEST_PAUSE contains the code to fork the test with the -c option.
+	 */
+	TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion
+ */
+void
+cleanup(void)
+{
+	/*
+	 * print timing stats if that option was specified.
+	 * print errno log if that option was specified.
+	 */
+	TEST_CLEANUP;
+
+	/* exit with return code appropriate for results */
+	tst_exit();
+	/*NOTREACHED*/
+}
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages03.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages03.c	2008-06-29 09:56:02.000000000 +0530
@@ -0,0 +1,237 @@
+/*
+ *   Copyright (c) 2008 Vijay Kumar B. <vijaykumar@xxxxxxxxxxxx>
+ *
+ *   Based on testcases/kernel/syscalls/waitpid/waitpid01.c
+ *   Original copyright message:
+ *
+ *   Copyright (c) International Business Machines  Corp., 2001
+ *
+ *   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
+ */
+
+/*
+ * NAME
+ *	move_pages03.c
+ *
+ * DESCRIPTION
+ *      Test movement of pages mapped by a process.
+ *
+ * ALGORITHM
+ *      1. Start the test case program as root.
+ *      2. Allocate a shared memory in NUMA node A.
+ *      3. Fork another process.
+ *      4. Use move_pages() to move the pages to NUMA node B, with the
+ *         MPOL_MF_MOVE_ALL.
+ *      5. Check if all pages are in node B.
+ *
+ * USAGE:  <for command-line>
+ *      move_pages03 [-c n] [-i n] [-I x] [-P x] [-t]
+ *      where,  -c n : Run n copies concurrently.
+ *              -i n : Execute test n times.
+ *              -I x : Execute test for x seconds.
+ *              -P x : Pause for x seconds between iterations.
+ *              -t   : Turn on syscall timing.
+ *
+ * History
+ *	05/2008 Vijay Kumar
+ *		Initial Version.
+ *
+ * Restrictions
+ *	None
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <signal.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <numa.h>
+
+#include <test.h>
+#include <usctest.h>
+
+#include "move_pages_support.h"
+
+#define TEST_PAGES 2
+#define TEST_NODES 2
+
+enum {
+	SEM_CHILD_SETUP,
+	SEM_PARENT_TEST,
+
+	MAX_SEMS
+};
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "move_pages03";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+/*
+ * child() - touches shared pages, and waits for signal from parent.
+ * @pages: shared pages allocated in parent
+ * @sem: semaphore to sync with parent
+ */
+void
+child(void **pages, sem_t *sem)
+{
+	int i;
+
+	for (i = 0; i < TEST_PAGES; i++) {
+		char *page;
+
+		page = pages[i];
+		page[0] = 0xAA;
+	}
+
+	/* Setup complete. Ask parent to continue. */
+	if (sem_post(&sem[SEM_CHILD_SETUP]) == -1)
+		tst_resm(TWARN, "error post semaphore: %s", strerror(errno));
+
+	/* Wait for testcase in parent to complete. */
+	if (sem_wait(&sem[SEM_PARENT_TEST]) == -1)
+		tst_resm(TWARN, "error wait semaphore: %s", strerror(errno));
+
+	exit(0);
+}
+
+int main(int argc, char **argv)
+{
+	unsigned int i;
+	int lc;				/* loop counter */
+	char *msg;			/* message returned from parse_opts */
+	unsigned int from_node = 0;
+	unsigned int to_node = 1;
+
+	/* parse standard options */
+	msg = parse_opts(argc, argv, (option_t *) NULL, NULL);
+	if (msg != NULL) {
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+		tst_exit();
+		/* NOTREACHED */
+	}
+
+	setup();
+
+	/* check for looping state if -i option is given */
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		void *pages[TEST_PAGES] = { 0 };
+		int nodes[TEST_PAGES];
+		int status[TEST_PAGES];
+		int ret;
+		pid_t cpid;
+		sem_t *sem;
+
+		/* reset Tst_count in case we are looping */
+		Tst_count = 0;
+
+		ret = alloc_shared_pages_on_node(pages, TEST_PAGES,
+						 from_node);
+		if (ret == -1)
+			continue;
+
+
+		for (i = 0; i < TEST_PAGES; i++) {
+			nodes[i] = to_node;
+		}
+
+		sem = alloc_sem(MAX_SEMS);
+		if (sem == NULL) {
+			goto err_free_pages;
+		}
+
+		/*
+		 * Fork a child process so that the shared pages are
+		 * now really shared between two processes.
+		 */
+		cpid = fork();
+		if (cpid == -1) {
+			tst_resm(TBROK, "forking child failed: %s",
+				 strerror(errno));
+			goto err_free_sem;
+		} else if (cpid == 0) {
+			child(pages, sem);
+		}
+
+		/* Wait for child to setup and signal. */
+		if (sem_wait(&sem[SEM_CHILD_SETUP]) == -1)
+			tst_resm(TWARN, "error wait semaphore: %s",
+				 strerror(errno));
+
+		ret = numa_move_pages(0, TEST_PAGES, pages, nodes,
+				      status, MPOL_MF_MOVE_ALL);
+		TEST_ERRNO = errno;
+		if (ret != 0) {
+			tst_resm(TFAIL, "retrieving NUMA nodes failed");
+			goto err_kill_child;
+		}
+
+		verify_pages_on_node(status, TEST_PAGES, to_node);
+
+	err_kill_child:
+		/* Test done. Ask child to terminate. */
+		if (sem_post(&sem[SEM_PARENT_TEST]) == -1)
+			tst_resm(TWARN, "error post semaphore: %s",
+				 strerror(errno));
+		/* Read the status, no zombies! */
+		wait(NULL);
+	err_free_sem:
+		free_sem(sem, MAX_SEMS);
+	err_free_pages:
+		free_shared_pages(pages, TEST_PAGES);
+	}
+
+	cleanup();
+	/* NOT REACHED */
+
+	return 0;
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+	/* capture signals */
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	check_config(TEST_NODES);
+
+	/* Pause if that option was specified
+	 * TEST_PAUSE contains the code to fork the test with the -c option.
+	 */
+	TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion
+ */
+void
+cleanup(void)
+{
+	/*
+	 * print timing stats if that option was specified.
+	 * print errno log if that option was specified.
+	 */
+	TEST_CLEANUP;
+
+	/* exit with return code appropriate for results */
+	tst_exit();
+	/*NOTREACHED*/
+}
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages_support.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages_support.c	2008-06-29 22:04:00.000000000 +0530
@@ -0,0 +1,390 @@
+/*
+ *   Copyright (c) 2008 Vijay Kumar B. <vijaykumar@xxxxxxxxxxxx>
+ *
+ *   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
+ */
+
+#include <sys/mman.h>
+#include <syscall.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <numa.h>
+#include <errno.h>
+
+#include <test.h>
+#include <usctest.h>
+#include <linux_syscall_numbers.h>
+
+#include "move_pages_support.h"
+
+#ifndef __NR_move_pages
+	int arch_support = 0;
+#else
+	int arch_support = 1;
+#endif
+
+long
+get_page_size()
+{
+	return sysconf(_SC_PAGESIZE);
+}
+
+/*
+ * free_pages() - free an array of pages
+ * @pages: array of page pointers to be freed
+ * @num: no. of pages in the array
+ */
+void
+free_pages(void **pages, unsigned int num)
+{
+	int i;
+	size_t onepage = get_page_size();
+
+	for (i = 0; i < num; i++) {
+		if (pages[i] != NULL) {
+			numa_free(pages[i], onepage);
+		}
+	}
+}
+
+/*
+ * alloc_pages_on_nodes() - allocate pages on specified NUMA nodes
+ * @pages: array in which the page pointers will be stored
+ * @num: no. of pages to allocate
+ * @nodes: array of NUMA nodes
+ *
+ * A page will be allocated in each node specified by @nodes, and the
+ * page pointers will be stored in @pages array.
+ *
+ * RETURNS:
+ * 0 on success, -1 on allocation failure.
+ */
+int
+alloc_pages_on_nodes(void **pages, unsigned int num, int *nodes)
+{
+	int i;
+	size_t onepage = get_page_size();
+
+	for (i = 0; i < num; i++) {
+		pages[i] = NULL;
+	}
+
+	for (i = 0; i < num; i++) {
+		char *page;
+
+		pages[i] = numa_alloc_onnode(onepage, nodes[i]);
+		if (pages[i] == NULL) {
+			tst_resm(TBROK, "allocation of page on node "
+				 "%d failed", nodes[i]);
+			break;
+		}
+
+		/* Touch the page, to force allocation. */
+		page = pages[i];
+		page[0] = i;
+	}
+
+	if (i == num)
+		return 0;
+
+	free_pages(pages, num);
+
+	return -1;
+}
+
+/*
+ * alloc_pages_linear() - allocate pages in each NUMA node
+ * @pages: array in which the page pointers will be stored
+ * @num: no. of pages to allocate
+ *
+ * Pages will be allocated one from each NUMA node, in an interleaved
+ * fashion.
+ *
+ * RETURNS:
+ * 0 on success, -1 on allocation failure.
+ */
+int
+alloc_pages_linear(void **pages, unsigned int num)
+{
+	unsigned int i;
+	unsigned int n;
+	int nodes[num];
+
+	n = 0;
+	for (i = 0; i < num; i++) {
+		nodes[i] = n;
+
+		n++;
+		if (n > numa_max_node())
+			n = 0;
+	}
+
+	return alloc_pages_on_nodes(pages, num, nodes);
+}
+
+/*
+ * alloc_pages_on_node() - allocate pages on specified NUMA node
+ * @pages: array in which the page pointers will be stored
+ * @num: no. of pages to allocate
+ * @node: NUMA node from which to allocate pages
+ *
+ * Pages will be allocated from the NUMA node @node, and the page
+ * pointers will be stored in the @pages array.
+ *
+ * RETURNS:
+ * 0 on success, -1 on allocation failure.
+ */
+int
+alloc_pages_on_node(void **pages, unsigned int num, int node)
+{
+	unsigned int i;
+	int nodes[num];
+
+	for (i = 0; i < num; i++)
+		nodes[i] = node;
+
+	return alloc_pages_on_nodes(pages, num, nodes);
+}
+
+/*
+ * verify_pages_on_nodes() - verify pages are in specified nodes
+ * @status: the NUMA node of each page
+ * @num: the no. of pages
+ * @nodes: the expected NUMA nodes
+ */
+void
+verify_pages_on_nodes(int *status, unsigned int num, int *nodes)
+{
+	unsigned int i;
+
+	for (i = 0; i < num; i++) {
+		if (status[i] != nodes[i]) {
+			tst_resm(TFAIL, "page %d on node %d, "
+				 "expected on node %d", i,
+				 status[i], nodes[i]);
+			return;
+		}
+	}
+
+	tst_resm(TPASS, "pages are present in expected nodes");
+}
+
+/*
+ * verify_pages_linear() - verify pages are interleaved
+ * @status: the NUMA node of each page
+ * @num: the no. of pages
+ */
+void
+verify_pages_linear(int *status, unsigned int num)
+{
+	unsigned int i;
+	unsigned int n;
+	int nodes[num];
+
+	n = 0;
+	for (i = 0; i < num; i++) {
+		nodes[i] = i;
+
+		n++;
+		if (n > numa_max_node())
+			n = 0;
+	}
+
+	verify_pages_on_nodes(status, num, nodes);
+}
+
+/*
+ * verify_pages_on_node() - verify pages are in specified node
+ * @status: the NUMA node of each page
+ * @num: the no. of pages
+ * @node: the expected NUMA node
+ */
+void
+verify_pages_on_node(int *status, unsigned int num, int node)
+{
+	unsigned int i;
+	int nodes[num];
+
+	for (i = 0; i < num; i++) {
+		nodes[i] = node;
+	}
+
+	verify_pages_on_nodes(status, num, nodes);
+}
+
+/*
+ * alloc_shared_pages_on_node() - allocate shared pages on a NUMA node
+ * @pages: array to store the allocated pages
+ * @num: the no. of pages to allocate
+ * @node: the node in which the pages should be allocated
+ *
+ * RETURNS:
+ * 0 on success, -1 on allocation failure
+ */
+int
+alloc_shared_pages_on_node(void **pages, unsigned int num,
+			   int node)
+{
+	char *shared;
+	unsigned int i;
+	int nodes[num];
+	size_t total_size = num * get_page_size();
+
+	shared = mmap(NULL, total_size,
+		      PROT_READ | PROT_WRITE,
+		      MAP_SHARED | MAP_ANONYMOUS, 0, 0);
+	if (shared == MAP_FAILED) {
+		tst_resm(TBROK, "allocation of shared pages failed: %s",
+			 strerror(errno));
+		return -1;
+	}
+
+	numa_tonode_memory(shared, total_size, node);
+
+	for (i = 0; i < num; i++) {
+		char *page;
+
+		pages[i] = shared;
+		shared += get_page_size();
+
+		nodes[i] = node;
+
+		/* Touch the page to force allocation */
+		page = pages[i];
+		page[0] = i;
+	}
+
+	return 0;
+}
+
+/*
+ * free_shared_pages() - free shared pages
+ * @pages: array of pages to be freed
+ * @num: the no. of pages to free
+ */
+void
+free_shared_pages(void **pages, unsigned int num)
+{
+	int ret;
+
+	ret = munmap(pages[0], num * get_page_size());
+	if (ret == -1)
+		tst_resm(TWARN, "unmapping of shared pages failed: %s",
+			 strerror(errno));
+}
+
+/*
+ * alloc_sem() - allocate semaphores
+ * @num - no. of semaphores to create
+ *
+ * Allocate and initialize semaphores in a shared memory area, so that
+ * the semaphore can be used accross processes.
+ *
+ * RETURNS:
+ * Array of initialized semaphores.
+ */
+sem_t *
+alloc_sem(int num)
+{
+	sem_t *sem;
+	void *sem_mem;
+	int i, ret;
+
+	sem_mem = mmap(NULL, get_page_size(),
+		       PROT_READ | PROT_WRITE,
+		       MAP_SHARED | MAP_ANONYMOUS, 0, 0);
+	if (sem_mem == MAP_FAILED) {
+		tst_resm(TBROK, "allocation of semaphore page failed: %s",
+			 strerror(errno));
+		goto err_exit;
+	}
+
+	sem = sem_mem;
+
+	for (i = 0; i < num; i++) {
+		ret = sem_init(&sem[i], 1, 0);
+		if (ret == -1) {
+			tst_resm(TBROK, "semaphore initialization failed: %s",
+				 strerror(errno));
+			goto err_free_mem;
+		}
+	}
+
+	return sem;
+
+ err_free_mem:
+	ret = munmap(sem_mem, get_page_size());
+	if (ret == -1)
+		tst_resm(TWARN, "error freeing semaphore memory: %s",
+			 strerror(errno));
+ err_exit:
+	return NULL;
+}
+
+/*
+ * free_sem() - free semaphores
+ * @sem - array of semphores to be freed
+ * @num - no. of semaphores in the array
+ */
+void
+free_sem(sem_t *sem, int num)
+{
+	int i;
+	int ret;
+
+	for (i = 0; i < num; i++) {
+		ret = sem_destroy(&sem[i]);
+		if (ret == -1)
+			tst_resm(TWARN, "error destroying semaphore: %s",
+				 strerror(errno));
+	}
+
+	ret = munmap(sem, get_page_size());
+	if (ret == -1)
+		tst_resm(TWARN, "error freeing semaphore memory: %s",
+			 strerror(errno));
+}
+
+/*
+ * check_config() - check for required configuration
+ * @min_nodes: the minimum required NUMA nodes
+ *
+ * Checks if numa support is availabe, kernel is >= 2.6.18, arch is
+ * one of the supported architectures.
+ */
+void
+check_config(unsigned int min_nodes)
+{
+	if (numa_available() < 0) {
+		tst_resm(TCONF, "NUMA support is not available");
+		tst_exit();
+	}
+
+	if (numa_max_node() < (min_nodes - 1)) {
+		tst_resm(TCONF, "atleast 2 NUMA nodes are required");
+		tst_exit();
+	}
+
+	if (tst_kvercmp(2, 6, 18) < 0) {
+		tst_resm(TCONF, "2.6.18 or greater kernel required");
+		tst_exit();
+	}
+
+	if (arch_support == 0) {
+		tst_resm(TCONF, "this arch does not support move_pages");
+		tst_exit();
+	}
+}
+
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages_support.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages_support.h	2008-06-29 22:04:28.000000000 +0530
@@ -0,0 +1,45 @@
+/*
+ *   Copyright (c) 2008 Vijay Kumar B. <vijaykumar@xxxxxxxxxxxx>
+ *
+ *   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
+ */
+
+#ifndef MOVE_PAGES_SUPPORT_H
+#define MOVE_PAGES_SUPPORT_H
+
+#include <numaif.h>
+#include <semaphore.h>
+
+long get_page_size();
+
+void free_pages(void **pages, unsigned int num);
+
+int alloc_pages_on_nodes(void **pages, unsigned int num, int *nodes);
+int alloc_pages_linear(void **pages, unsigned int num);
+int alloc_pages_on_node(void **pages, unsigned int num, int node);
+
+void verify_pages_on_nodes(int *status, unsigned int num, int *nodes);
+void verify_pages_linear(int *status, unsigned int num);
+void verify_pages_on_node(int *status, unsigned int num, int node);
+
+int alloc_shared_pages_on_node(void **pages, unsigned int num, int node);
+void free_shared_pages(void **pages, unsigned int num);
+
+sem_t *alloc_sem(int num);
+void free_sem(sem_t *sem, int num);
+
+void check_config(unsigned int min_nodes);
+
+#endif
Index: ltp-mod/runtest/numa
===================================================================
--- ltp-mod.orig/runtest/numa	2008-06-29 09:54:54.000000000 +0530
+++ ltp-mod/runtest/numa	2008-06-29 22:04:41.000000000 +0530
@@ -1 +1,14 @@
 Numa-testcases numa01.sh
+move_pages01 move_pages.sh 01
+move_pages02 move_pages.sh 02
+move_pages03 move_pages.sh 03
+move_pages04 move_pages.sh 04
+move_pages05 move_pages.sh 05
+move_pages06 move_pages.sh 06
+move_pages07 move_pages.sh 07
+move_pages08 move_pages.sh 08
+move_pages09 move_pages.sh 09
+move_pages10 move_pages.sh 10
+move_pages11 move_pages.sh 11
+move_pages12 move_pages.sh 12
+
Index: ltp-mod/runtest/syscalls
===================================================================
--- ltp-mod.orig/runtest/syscalls	2008-06-29 09:55:58.000000000 +0530
+++ ltp-mod/runtest/syscalls	2008-06-29 22:04:41.000000000 +0530
@@ -445,6 +445,19 @@
 #mount03 mount03 -D /dev/...
 #mount04 mount04 -D /dev/...

+move_pages01 move_pages.sh 01
+move_pages02 move_pages.sh 02
+move_pages03 move_pages.sh 03
+move_pages04 move_pages.sh 04
+move_pages05 move_pages.sh 05
+move_pages06 move_pages.sh 06
+move_pages07 move_pages.sh 07
+move_pages08 move_pages.sh 08
+move_pages09 move_pages.sh 09
+move_pages10 move_pages.sh 10
+move_pages11 move_pages.sh 11
+move_pages12 move_pages.sh 12
+
 mprotect01 mprotect01
 mprotect02 mprotect02
 mprotect03 mprotect03
Index: ltp-mod/Makefile
===================================================================
--- ltp-mod.orig/Makefile	2008-06-29 09:54:54.000000000 +0530
+++ ltp-mod/Makefile	2008-06-29 09:56:02.000000000 +0530
@@ -37,8 +37,10 @@
 RANLIB=$(CROSS_COMPILER)ranlib
 endif

+HAS_NUMA=$(shell sh tools/scripts/numa_test.sh)
+
 export CFLAGS += -Wall $(CROSS_CFLAGS)
-export CC AR RANLIB LDFLAGS
+export CC AR RANLIB LDFLAGS HAS_NUMA

 -include config.mk

Index: ltp-mod/testcases/kernel/numa/Makefile
===================================================================
--- ltp-mod.orig/testcases/kernel/numa/Makefile	2008-06-29 09:54:54.000000000 +0530
+++ ltp-mod/testcases/kernel/numa/Makefile	2008-06-29 09:56:02.000000000 +0530
@@ -20,7 +20,7 @@

 LDLIBS += -L../../../lib -lltp 

-ifeq ($(shell sh test.sh),yes)    #its a numa machine
+ifeq ($(HAS_NUMA),yes)    #its a numa machine
 LDLIBS += -L../../../lib  -lnuma
 SRCS    = $(wildcard *.c)
 TARGETS = $(patsubst %.c,%,$(SRCS))
Index: ltp-mod/testcases/kernel/numa/test.sh
===================================================================
--- ltp-mod.orig/testcases/kernel/numa/test.sh	2008-06-29 09:54:54.000000000 +0530
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,53 +0,0 @@
-################################################################################
-##                                                                            ##
-## Copyright (c) International Business Machines  Corp., 2007                 ##
-##                                                                            ##
-## 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    ##
-##                                                                            ##
-################################################################################
-#   
-# Author         Pradeep Kumar Surisetty, pradeepkumars@xxxxxxxxxx
-#   
-# History        Nov 27 2007 -created- pradeep kumar surisetty
-#! /bin/sh
-#
-# File :         test.sh
-
-
-#!/bin/sh
-x=0
-chk_ifexist()
-{
-if [ ! -d /sys/devices/system/node ]
-then
-x=0
-else
-x=$(ls /sys/devices/system/node | wc -l)
-fi
-if [ $x -gt 1 ]
-then
-	if [ ! -f /usr/include/numa.h ]
-	then
-		echo no;
- 	else
-		echo yes;
-	fi	
-else
-        echo no;     #numa is not present
-
-fi
-}
-chk_ifexist
-
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages03.mode.sh
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages03.mode.sh	2008-06-29 09:56:02.000000000 +0530
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+failed() {
+	echo ""
+	echo "             ************** WARNING **************"
+	echo "    Cannot change permission or ownership of \"move_pages03\"."
+	echo "                   Test move_pages03 will fail"
+	echo "                   Run "make install" as root."
+	echo "             *************************************"
+	sleep 2
+}
+
+if [ -f move_pages03 ]; then
+    chown root move_pages03 || failed
+    chmod 04755 move_pages03 || failed
+fi
+
+exit 0
Index: ltp-mod/tools/scripts/numa_test.sh
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/tools/scripts/numa_test.sh	2008-06-29 09:56:02.000000000 +0530
@@ -0,0 +1,53 @@
+#############################################################################
+##
+## Copyright (c) International Business Machines  Corp., 2007
+##
+## 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
+##
+#############################################################################
+#
+# Author         Pradeep Kumar Surisetty, pradeepkumars@xxxxxxxxxx
+#
+# History        Nov 27 2007 -created- pradeep kumar surisetty
+#! /bin/sh
+#
+# File :         numa_test.sh
+
+
+#!/bin/sh
+x=0
+chk_ifexist()
+{
+if [ ! -d /sys/devices/system/node ]
+then
+x=0
+else
+x=$(ls /sys/devices/system/node | wc -l)
+fi
+if [ $x -gt 1 ]
+then
+	if [ ! -f /usr/include/numa.h ]
+	then
+		echo no;
+ 	else
+		echo yes;
+	fi
+else
+        echo no;     #numa is not present
+
+fi
+}
+chk_ifexist
+
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages.sh
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages.sh	2008-06-29 21:42:37.000000000 +0530
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+if [ -z "$1" ]; then
+    echo "Usage: move_pages.sh <test-number>"
+    exit 1
+fi
+
+testprog=move_pages${1}
+
+shopt -s execfail
+exec $testprog
+
+export TCID=$testprog
+export TST_TOTAL=1
+export TST_COUNT=0
+tst_resm TCONF "libnuma and NUMA support is required for this testcase"
+
+tst_exit
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages04.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages04.c	2008-06-29 22:04:41.000000000 +0530
@@ -0,0 +1,185 @@
+/*
+ *   Copyright (c) 2008 Vijay Kumar B. <vijaykumar@xxxxxxxxxxxx>
+ *
+ *   Based on testcases/kernel/syscalls/waitpid/waitpid01.c
+ *   Original copyright message:
+ *
+ *   Copyright (c) International Business Machines  Corp., 2001
+ *
+ *   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
+ */
+
+/*
+ * NAME
+ *	move_pages04.c
+ *
+ * DESCRIPTION
+ *      Failure when page does not exit.
+ *
+ * ALGORITHM
+ *
+ *      1. Pass a page that does not exit as one of the page addresses
+ *         to move_pages().
+ *      2. Check if the corresponding status is set to -ENOENT.
+ *
+ * USAGE:  <for command-line>
+ *      move_pages04 [-c n] [-i n] [-I x] [-P x] [-t]
+ *      where,  -c n : Run n copies concurrently.
+ *              -i n : Execute test n times.
+ *              -I x : Execute test for x seconds.
+ *              -P x : Pause for x seconds between iterations.
+ *              -t   : Turn on syscall timing.
+ *
+ * History
+ *	05/2008 Vijay Kumar
+ *		Initial Version.
+ *
+ * Restrictions
+ *	None
+ */
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <numa.h>
+
+#include <test.h>
+#include <usctest.h>
+
+#include "move_pages_support.h"
+
+#define TEST_PAGES 2
+#define TEST_NODES 2
+#define TOUCHED_PAGES 1
+#define UNTOUCHED_PAGE (TEST_PAGES - 1)
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "move_pages04";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+typedef void (*sighandler_t)(int);
+
+int main(int argc, char **argv)
+{
+	unsigned int i;
+	int lc;				/* loop counter */
+	char *msg;			/* message returned from parse_opts */
+	unsigned int from_node = 0;
+	unsigned int to_node = 1;
+
+	/* parse standard options */
+	msg = parse_opts(argc, argv, (option_t *) NULL, NULL);
+	if (msg != NULL) {
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+		tst_exit();
+		/* NOTREACHED */
+	}
+
+	setup();
+
+	/* check for looping state if -i option is given */
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		void *pages[TEST_PAGES] = { 0 };
+		int nodes[TEST_PAGES];
+		int status[TEST_PAGES];
+		int ret;
+		unsigned long onepage = get_page_size();
+
+		/* reset Tst_count in case we are looping */
+		Tst_count = 0;
+
+		ret = alloc_pages_on_node(pages, TOUCHED_PAGES, from_node);
+		if (ret == -1)
+			continue;
+
+		/* Allocate page and do not touch it. */
+		pages[UNTOUCHED_PAGE] = numa_alloc_onnode(onepage, from_node);
+		if (pages[UNTOUCHED_PAGE] == NULL) {
+			tst_resm(TBROK, "failed allocating page on node %d",
+				 from_node);
+			goto err_free_pages;
+		}
+
+		for (i = 0; i < TEST_PAGES; i++)
+			nodes[i] = to_node;
+
+		ret = numa_move_pages(0, TEST_PAGES, pages, nodes,
+				      status, MPOL_MF_MOVE);
+		TEST_ERRNO = errno;
+		if (ret == -1) {
+			tst_resm(TFAIL, "move_pages unexpectedly failed: %s",
+				 strerror(errno));
+			goto err_free_pages;
+		}
+
+		if (status[UNTOUCHED_PAGE] == -ENOENT)
+			tst_resm(TPASS, "status[%d] set to expected -ENOENT",
+				 UNTOUCHED_PAGE);
+		else
+			tst_resm(TFAIL, "status[%d] is %d", UNTOUCHED_PAGE,
+				 status[UNTOUCHED_PAGE]);
+
+	err_free_pages:
+		/* This is capable of freeing both the touched and
+		 * untouched pages.
+		 */
+		free_pages(pages, TEST_PAGES);
+	}
+
+	cleanup();
+	/* NOT REACHED */
+
+	return 0;
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+	/* capture signals */
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	check_config(TEST_NODES);
+
+	/* Pause if that option was specified
+	 * TEST_PAUSE contains the code to fork the test with the -c option.
+	 */
+	TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion
+ */
+void
+cleanup(void)
+{
+	/*
+	 * print timing stats if that option was specified.
+	 * print errno log if that option was specified.
+	 */
+	TEST_CLEANUP;
+
+	/* exit with return code appropriate for results */
+	tst_exit();
+	/*NOTREACHED*/
+}
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages05.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages05.c	2008-06-29 22:04:41.000000000 +0530
@@ -0,0 +1,250 @@
+/*
+ *   Copyright (c) 2008 Vijay Kumar B. <vijaykumar@xxxxxxxxxxxx>
+ *
+ *   Based on testcases/kernel/syscalls/waitpid/waitpid01.c
+ *   Original copyright message:
+ *
+ *   Copyright (c) International Business Machines  Corp., 2001
+ *
+ *   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
+ */
+
+/*
+ * NAME
+ *	move_pages05.c
+ *
+ * DESCRIPTION
+ *      Test movement of pages mapped by a process.
+ *
+ * ALGORITHM
+ *      1. Start the test case program as root.
+ *      2. Allocate a shared memory in NUMA node A.
+ *      3. Fork another process.
+ *      4. Use move_pages() to move the pages to NUMA node B, without
+ *         the MPOL_MF_MOVE_ALL.
+ *      5. Check if the corresponding status is set to -EACCES.
+ *
+ * USAGE:  <for command-line>
+ *      move_pages05 [-c n] [-i n] [-I x] [-P x] [-t]
+ *      where,  -c n : Run n copies concurrently.
+ *              -i n : Execute test n times.
+ *              -I x : Execute test for x seconds.
+ *              -P x : Pause for x seconds between iterations.
+ *              -t   : Turn on syscall timing.
+ *
+ * History
+ *	05/2008 Vijay Kumar
+ *		Initial Version.
+ *
+ * Restrictions
+ *	None
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+#include <numa.h>
+
+#include <test.h>
+#include <usctest.h>
+
+#include "move_pages_support.h"
+
+#define SHARED_PAGE 0
+#define N_SHARED_PAGES 1
+#define UNSHARED_PAGE 1
+#define N_UNSHARED_PAGES 1
+#define N_TEST_PAGES (N_SHARED_PAGES + N_UNSHARED_PAGES)
+#define N_TEST_NODES 2
+
+enum {
+	SEM_CHILD_SETUP,
+	SEM_PARENT_TEST,
+
+	MAX_SEMS
+};
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "move_pages05";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+/*
+ * child() - touches pages, and waits for signal from parent.
+ * @pages: shared pages allocated in parent
+ */
+void child(void **pages, sem_t *sem)
+{
+	int i;
+
+	for (i = 0; i < N_TEST_PAGES; i++) {
+		char *page;
+
+		page = pages[i];
+		page[0] = 0xAA;
+	}
+
+	/* Setup complete. Ask parent to continue. */
+	if (sem_post(&sem[SEM_CHILD_SETUP]) == -1)
+		tst_resm(TWARN, "error post semaphore: %s", strerror(errno));
+
+	/* Wait for testcase in parent to complete. */
+	if (sem_wait(&sem[SEM_PARENT_TEST]) == -1)
+		tst_resm(TWARN, "error wait semaphore: %s", strerror(errno));
+
+	exit(0);
+}
+
+int main(int argc, char **argv)
+{
+	unsigned int i;
+	int lc;				/* loop counter */
+	char *msg;			/* message returned from parse_opts */
+	unsigned int from_node = 0;
+	unsigned int to_node = 1;
+
+	/* parse standard options */
+	msg = parse_opts(argc, argv, (option_t *) NULL, NULL);
+	if (msg != NULL) {
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+		tst_exit();
+		/* NOTREACHED */
+	}
+
+	setup();
+
+	/* check for looping state if -i option is given */
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		void *pages[N_TEST_PAGES] = { 0 };
+		int nodes[N_TEST_PAGES];
+		int status[N_TEST_PAGES];
+		int ret;
+		pid_t cpid;
+		sem_t *sem;
+
+		/* reset Tst_count in case we are looping */
+		Tst_count = 0;
+
+		ret = alloc_shared_pages_on_node(pages + SHARED_PAGE,
+						 N_SHARED_PAGES,
+						 from_node);
+		if (ret == -1)
+			continue;
+
+		ret = alloc_pages_on_node(pages + UNSHARED_PAGE,
+					  N_UNSHARED_PAGES,
+					  from_node);
+		if (ret == -1)
+			goto err_free_shared;
+
+		for (i = 0; i < N_TEST_PAGES; i++) {
+			nodes[i] = to_node;
+		}
+
+		sem = alloc_sem(MAX_SEMS);
+		if (sem == NULL) {
+			goto err_free_unshared;
+		}
+
+		/*
+		 * Fork a child process so that the shared pages are
+		 * now really shared between two processes.
+		 */
+		cpid = fork();
+		if (cpid == -1) {
+			tst_resm(TBROK, "forking child failed");
+			goto err_free_sem;
+		} else if (cpid == 0) {
+			child(pages, sem);
+		}
+
+		/* Wait for child to setup and signal. */
+		if (sem_wait(&sem[SEM_CHILD_SETUP]) == -1)
+			tst_resm(TWARN, "error wait semaphore: %s",
+				 strerror(errno));
+
+		ret = numa_move_pages(0, N_TEST_PAGES, pages, nodes,
+				      status, MPOL_MF_MOVE);
+		TEST_ERRNO = errno;
+		if (ret == -1) {
+			tst_resm(TFAIL, "move_pages unexpectedly failed: %s",
+				 strerror(errno));
+			goto err_kill_child;
+		}
+
+		if (status[SHARED_PAGE] == -EACCES)
+			tst_resm(TPASS, "status[%d] set to expected -EACCES",
+				 SHARED_PAGE);
+		else
+			tst_resm(TFAIL, "status[%d] is %d",
+				 SHARED_PAGE, status[SHARED_PAGE]);
+
+	err_kill_child:
+		/* Test done. Ask child to terminate. */
+		if (sem_post(&sem[SEM_PARENT_TEST]) == -1)
+			tst_resm(TWARN, "error post semaphore: %s",
+				 strerror(errno));
+		/* Read the status, no zombies! */
+		wait(NULL);
+	err_free_sem:
+		free_sem(sem, MAX_SEMS);
+	err_free_unshared:
+		free_pages(pages + UNSHARED_PAGE, N_UNSHARED_PAGES);
+	err_free_shared:
+		free_shared_pages(pages + SHARED_PAGE, N_SHARED_PAGES);
+	}
+
+	cleanup();
+	/* NOT REACHED */
+
+	return 0;
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+	/* capture signals */
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	check_config(N_TEST_NODES);
+
+	/* Pause if that option was specified
+	 * TEST_PAUSE contains the code to fork the test with the -c option.
+	 */
+	TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion
+ */
+void
+cleanup(void)
+{
+	/*
+	 * print timing stats if that option was specified.
+	 * print errno log if that option was specified.
+	 */
+	TEST_CLEANUP;
+
+	/* exit with return code appropriate for results */
+	tst_exit();
+	/*NOTREACHED*/
+}
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages06.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages06.c	2008-06-29 22:04:41.000000000 +0530
@@ -0,0 +1,179 @@
+/*
+ *   Copyright (c) 2008 Vijay Kumar B. <vijaykumar@xxxxxxxxxxxx>
+ *
+ *   Based on testcases/kernel/syscalls/waitpid/waitpid01.c
+ *   Original copyright message:
+ *
+ *   Copyright (c) International Business Machines  Corp., 2001
+ *
+ *   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
+ */
+
+/*
+ * NAME
+ *	move_pages06.c
+ *
+ * DESCRIPTION
+ *      Failure when moving mlocked pages.
+ *
+ * ALGORITHM
+ *
+ *      1. Pass a pointer to a mlocked page to to move_pages().
+ *      2. Check if the corresponding status is set to -EPERM.
+ *
+ * USAGE:  <for command-line>
+ *      move_pages06 [-c n] [-i n] [-I x] [-P x] [-t]
+ *      where,  -c n : Run n copies concurrently.
+ *              -i n : Execute test n times.
+ *              -I x : Execute test for x seconds.
+ *              -P x : Pause for x seconds between iterations.
+ *              -t   : Turn on syscall timing.
+ *
+ * History
+ *	05/2008 Vijay Kumar
+ *		Initial Version.
+ *
+ * Restrictions
+ *	None
+ */
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+#include <numa.h>
+
+#include <test.h>
+#include <usctest.h>
+
+#include "move_pages_support.h"
+
+#define TEST_PAGES 2
+#define TEST_NODES 2
+#define MLOCKED_PAGE 0
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "move_pages06";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+int main(int argc, char **argv)
+{
+	unsigned int i;
+	int lc;				/* loop counter */
+	char *msg;			/* message returned from parse_opts */
+	unsigned int from_node = 0;
+	unsigned int to_node = 1;
+
+	/* parse standard options */
+	msg = parse_opts(argc, argv, (option_t *) NULL, NULL);
+	if (msg != NULL) {
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+		tst_exit();
+		/* NOTREACHED */
+	}
+
+	setup();
+
+	/* check for looping state if -i option is given */
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		void *pages[TEST_PAGES] = { 0 };
+		int nodes[TEST_PAGES];
+		int status[TEST_PAGES];
+		int ret;
+		unsigned long onepage = get_page_size();
+
+		/* reset Tst_count in case we are looping */
+		Tst_count = 0;
+
+		ret = alloc_pages_on_node(pages, TEST_PAGES, from_node);
+		if (ret == -1)
+			continue;
+
+		ret = mlock(&pages[MLOCKED_PAGE], onepage);
+		if (ret == -1) {
+			tst_resm(TBROK, "mlocking page failed: %s",
+				 strerror(errno));
+			goto err_free_pages;
+		}
+
+		for (i = 0; i < TEST_PAGES; i++)
+			nodes[i] = to_node;
+
+		ret = numa_move_pages(0, TEST_PAGES, pages, nodes,
+				      status, MPOL_MF_MOVE);
+		TEST_ERRNO = errno;
+		if (ret == -1) {
+			tst_resm(TFAIL, "move_pages unexpectedly failed: %s",
+				 strerror(errno));
+			goto err_free_pages;
+		}
+
+		if (status[MLOCKED_PAGE] == -EPERM)
+			tst_resm(TPASS, "status[%d] set to expected -EPERM",
+				 MLOCKED_PAGE);
+		else
+			tst_resm(TFAIL, "status[%d] is %d", MLOCKED_PAGE,
+				 status[MLOCKED_PAGE]);
+
+	err_free_pages:
+		/* This is capable of freeing both mlocked and
+		 * non-mlocked pages.
+		 */
+		free_pages(pages, TEST_PAGES);
+	}
+
+	cleanup();
+	/* NOT REACHED */
+
+	return 0;
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+	/* capture signals */
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	check_config(TEST_NODES);
+
+	/* Pause if that option was specified
+	 * TEST_PAUSE contains the code to fork the test with the -c option.
+	 */
+	TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion
+ */
+void
+cleanup(void)
+{
+	/*
+	 * print timing stats if that option was specified.
+	 * print errno log if that option was specified.
+	 */
+	TEST_CLEANUP;
+
+	/* exit with return code appropriate for results */
+	tst_exit();
+	/*NOTREACHED*/
+}
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages07.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages07.c	2008-06-29 22:04:41.000000000 +0530
@@ -0,0 +1,161 @@
+/*
+ *   Copyright (c) 2008 Vijay Kumar B. <vijaykumar@xxxxxxxxxxxx>
+ *
+ *   Based on testcases/kernel/syscalls/waitpid/waitpid01.c
+ *   Original copyright message:
+ *
+ *   Copyright (c) International Business Machines  Corp., 2001
+ *
+ *   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
+ */
+
+/*
+ * NAME
+ *	move_pages07.c
+ *
+ * DESCRIPTION
+ *      Failure when NUMA node is invalid.
+ *
+ * ALGORITHM
+ *
+ *      1. Pass a non-existent NUMA node number to move_pages().
+ *      2. Check if errno is set to ENODEV.
+ *
+ * USAGE:  <for command-line>
+ *      move_pages07 [-c n] [-i n] [-I x] [-P x] [-t]
+ *      where,  -c n : Run n copies concurrently.
+ *              -i n : Execute test n times.
+ *              -I x : Execute test for x seconds.
+ *              -P x : Pause for x seconds between iterations.
+ *              -t   : Turn on syscall timing.
+ *
+ * History
+ *	05/2008 Vijay Kumar
+ *		Initial Version.
+ *
+ * Restrictions
+ *	None
+ */
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+#include <numa.h>
+
+#include <test.h>
+#include <usctest.h>
+
+#include "move_pages_support.h"
+
+#define TEST_PAGES 2
+#define TEST_NODES 2
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "move_pages07";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+int main(int argc, char **argv)
+{
+	unsigned int i;
+	int lc;				/* loop counter */
+	char *msg;			/* message returned from parse_opts */
+	unsigned int from_node = 0;
+	unsigned int to_node;
+
+	/* parse standard options */
+	msg = parse_opts(argc, argv, (option_t *) NULL, NULL);
+	if (msg != NULL) {
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+		tst_exit();
+		/* NOTREACHED */
+	}
+
+	setup();
+
+	/* check for looping state if -i option is given */
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		void *pages[TEST_PAGES] = { 0 };
+		int nodes[TEST_PAGES];
+		int status[TEST_PAGES];
+		int ret;
+
+		/* reset Tst_count in case we are looping */
+		Tst_count = 0;
+
+		ret = alloc_pages_on_node(pages, TEST_PAGES, from_node);
+		if (ret == -1)
+			continue;
+
+		to_node = numa_max_node() + 1;
+		for (i = 0; i < TEST_PAGES; i++)
+			nodes[i] = to_node;
+
+		ret = numa_move_pages(0, TEST_PAGES, pages, nodes,
+				      status, MPOL_MF_MOVE);
+		TEST_ERRNO = errno;
+		if (ret == -1 && errno == ENODEV)
+			tst_resm(TPASS, "move_pages failed with "
+				 "ENODEV as expected");
+		else
+			tst_resm(TFAIL, "move pages did not fail "
+				 "with ENODEV");
+
+		free_pages(pages, TEST_PAGES);
+	}
+
+	cleanup();
+	/* NOT REACHED */
+
+	return 0;
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+	/* capture signals */
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	check_config(TEST_NODES);
+
+	/* Pause if that option was specified
+	 * TEST_PAUSE contains the code to fork the test with the -c option.
+	 */
+	TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion
+ */
+void
+cleanup(void)
+{
+	/*
+	 * print timing stats if that option was specified.
+	 * print errno log if that option was specified.
+	 */
+	TEST_CLEANUP;
+
+	/* exit with return code appropriate for results */
+	tst_exit();
+	/*NOTREACHED*/
+}
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages08.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages08.c	2008-06-29 22:04:41.000000000 +0530
@@ -0,0 +1,171 @@
+/*
+ *   Copyright (c) 2008 Vijay Kumar B. <vijaykumar@xxxxxxxxxxxx>
+ *
+ *   Based on testcases/kernel/syscalls/waitpid/waitpid01.c
+ *   Original copyright message:
+ *
+ *   Copyright (c) International Business Machines  Corp., 2001
+ *
+ *   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
+ */
+
+/*
+ * NAME
+ *	move_pages08.c
+ *
+ * DESCRIPTION
+ *      Failure when PID is invalid.
+ *
+ * ALGORITHM
+ *
+ *      1. Pass a non-existent pid to move_pages().
+ *      2. Check if errno is set to ESRCH.
+ *
+ * USAGE:  <for command-line>
+ *      move_pages08 [-c n] [-i n] [-I x] [-P x] [-t]
+ *      where,  -c n : Run n copies concurrently.
+ *              -i n : Execute test n times.
+ *              -I x : Execute test for x seconds.
+ *              -P x : Pause for x seconds between iterations.
+ *              -t   : Turn on syscall timing.
+ *
+ * History
+ *	05/2008 Vijay Kumar
+ *		Initial Version.
+ *
+ * Restrictions
+ *	None
+ */
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+#include <numa.h>
+
+#include <test.h>
+#include <usctest.h>
+
+#include "move_pages_support.h"
+
+#define TEST_PAGES 2
+#define TEST_NODES 2
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "move_pages08";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+int main(int argc, char **argv)
+{
+	unsigned int i;
+	int lc;				/* loop counter */
+	char *msg;			/* message returned from parse_opts */
+	unsigned int from_node = 0;
+	unsigned int to_node = 1;
+
+	/* parse standard options */
+	msg = parse_opts(argc, argv, (option_t *) NULL, NULL);
+	if (msg != NULL) {
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+		tst_exit();
+		/* NOTREACHED */
+	}
+
+	setup();
+
+	/* check for looping state if -i option is given */
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		void *pages[TEST_PAGES] = { 0 };
+		int nodes[TEST_PAGES];
+		int status[TEST_PAGES];
+		int ret;
+		int ipid;
+
+		/* reset Tst_count in case we are looping */
+		Tst_count = 0;
+
+		ret = alloc_pages_on_node(pages, TEST_PAGES, from_node);
+		if (ret == -1)
+			continue;
+
+		for (i = 0; i < TEST_PAGES; i++)
+			nodes[i] = to_node;
+
+		ipid = fork();
+		if (ipid == -1) {
+			tst_resm(TBROK, "fork failed: %s", strerror(errno));
+			goto err_free_pages;
+		} if (ipid == 0)
+			exit(0);
+
+		wait(NULL);
+
+		ret = numa_move_pages(ipid, TEST_PAGES, pages, nodes,
+				      status, MPOL_MF_MOVE);
+		TEST_ERRNO = errno;
+		if (ret == -1 && errno == ESRCH)
+			tst_resm(TPASS, "move_pages failed with "
+				 "ESRCH as expected");
+		else
+			tst_resm(TFAIL, "move pages did not fail "
+				 "with ESRCH");
+
+	err_free_pages:
+		free_pages(pages, TEST_PAGES);
+	}
+
+	cleanup();
+	/* NOT REACHED */
+
+	return 0;
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+	/* capture signals */
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	check_config(TEST_NODES);
+
+	/* Pause if that option was specified
+	 * TEST_PAUSE contains the code to fork the test with the -c option.
+	 */
+	TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion
+ */
+void
+cleanup(void)
+{
+	/*
+	 * print timing stats if that option was specified.
+	 * print errno log if that option was specified.
+	 */
+	TEST_CLEANUP;
+
+	/* exit with return code appropriate for results */
+	tst_exit();
+	/*NOTREACHED*/
+}
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages09.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages09.c	2008-06-29 22:04:41.000000000 +0530
@@ -0,0 +1,160 @@
+/*
+ *   Copyright (c) 2008 Vijay Kumar B. <vijaykumar@xxxxxxxxxxxx>
+ *
+ *   Based on testcases/kernel/syscalls/waitpid/waitpid01.c
+ *   Original copyright message:
+ *
+ *   Copyright (c) International Business Machines  Corp., 2001
+ *
+ *   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
+ */
+
+/*
+ * NAME
+ *	move_pages09.c
+ *
+ * DESCRIPTION
+ *      Failure when the no. of pages is ULONG_MAX.
+ *
+ * ALGORITHM
+ *
+ *      1. Pass ULONG_MAX pages to move_pages().
+ *      2. Check if errno is set to E2BIG.
+ *
+ * USAGE:  <for command-line>
+ *      move_pages09 [-c n] [-i n] [-I x] [-P x] [-t]
+ *      where,  -c n : Run n copies concurrently.
+ *              -i n : Execute test n times.
+ *              -I x : Execute test for x seconds.
+ *              -P x : Pause for x seconds between iterations.
+ *              -t   : Turn on syscall timing.
+ *
+ * History
+ *	05/2008 Vijay Kumar
+ *		Initial Version.
+ *
+ * Restrictions
+ *	None
+ */
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+#include <numa.h>
+
+#include <test.h>
+#include <usctest.h>
+
+#include "move_pages_support.h"
+
+#define TEST_PAGES 2
+#define TEST_NODES 2
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "move_pages09";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+int main(int argc, char **argv)
+{
+	unsigned int i;
+	int lc;				/* loop counter */
+	char *msg;			/* message returned from parse_opts */
+	unsigned int from_node = 0;
+	unsigned int to_node = 1;
+
+	/* parse standard options */
+	msg = parse_opts(argc, argv, (option_t *) NULL, NULL);
+	if (msg != NULL) {
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+		tst_exit();
+		/* NOTREACHED */
+	}
+
+	setup();
+
+	/* check for looping state if -i option is given */
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		void *pages[TEST_PAGES] = { 0 };
+		int nodes[TEST_PAGES];
+		int status[TEST_PAGES];
+		int ret;
+
+		/* reset Tst_count in case we are looping */
+		Tst_count = 0;
+
+		ret = alloc_pages_on_node(pages, TEST_PAGES, from_node);
+		if (ret == -1)
+			continue;
+
+		for (i = 0; i < TEST_PAGES; i++)
+			nodes[i] = to_node;
+
+		ret = numa_move_pages(0, ULONG_MAX, pages, nodes,
+				      status, MPOL_MF_MOVE);
+		TEST_ERRNO = errno;
+		if (ret == -1 && errno == E2BIG)
+			tst_resm(TPASS, "move_pages failed with "
+				 "E2BIG as expected");
+		else
+			tst_resm(TFAIL, "move pages did not fail "
+				 "with E2BIG");
+
+		free_pages(pages, TEST_PAGES);
+	}
+
+	cleanup();
+	/* NOT REACHED */
+
+	return 0;
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+	/* capture signals */
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	check_config(TEST_NODES);
+
+	/* Pause if that option was specified
+	 * TEST_PAUSE contains the code to fork the test with the -c option.
+	 */
+	TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion
+ */
+void
+cleanup(void)
+{
+	/*
+	 * print timing stats if that option was specified.
+	 * print errno log if that option was specified.
+	 */
+	TEST_CLEANUP;
+
+	/* exit with return code appropriate for results */
+	tst_exit();
+	/*NOTREACHED*/
+}
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages10.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages10.c	2008-06-29 22:04:41.000000000 +0530
@@ -0,0 +1,159 @@
+/*
+ *   Copyright (c) 2008 Vijay Kumar B. <vijaykumar@xxxxxxxxxxxx>
+ *
+ *   Based on testcases/kernel/syscalls/waitpid/waitpid01.c
+ *   Original copyright message:
+ *
+ *   Copyright (c) International Business Machines  Corp., 2001
+ *
+ *   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
+ */
+
+/*
+ * NAME
+ *	move_pages10.c
+ *
+ * DESCRIPTION
+ *      Failure when all pages are in required node.
+ *
+ * ALGORITHM
+ *
+ *      1. Pass the actual NUMA node number for each page to move_pages().
+ *      2. Check if errno is set to ENOENT.
+ *
+ * USAGE:  <for command-line>
+ *      move_pages10 [-c n] [-i n] [-I x] [-P x] [-t]
+ *      where,  -c n : Run n copies concurrently.
+ *              -i n : Execute test n times.
+ *              -I x : Execute test for x seconds.
+ *              -P x : Pause for x seconds between iterations.
+ *              -t   : Turn on syscall timing.
+ *
+ * History
+ *	05/2008 Vijay Kumar
+ *		Initial Version.
+ *
+ * Restrictions
+ *	None
+ */
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+#include <numa.h>
+
+#include <test.h>
+#include <usctest.h>
+
+#include "move_pages_support.h"
+
+#define TEST_PAGES 2
+#define TEST_NODES 2
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "move_pages10";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+int main(int argc, char **argv)
+{
+	unsigned int i;
+	int lc;				/* loop counter */
+	char *msg;			/* message returned from parse_opts */
+	unsigned int from_node = 0;
+
+	/* parse standard options */
+	msg = parse_opts(argc, argv, (option_t *) NULL, NULL);
+	if (msg != NULL) {
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+		tst_exit();
+		/* NOTREACHED */
+	}
+
+	setup();
+
+	/* check for looping state if -i option is given */
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		void *pages[TEST_PAGES] = { 0 };
+		int nodes[TEST_PAGES];
+		int status[TEST_PAGES];
+		int ret;
+
+		/* reset Tst_count in case we are looping */
+		Tst_count = 0;
+
+		ret = alloc_pages_on_node(pages, TEST_PAGES, from_node);
+		if (ret == -1)
+			continue;
+
+		for (i = 0; i < TEST_PAGES; i++)
+			nodes[i] = from_node;
+
+		ret = numa_move_pages(0, TEST_PAGES, pages, nodes,
+				      status, MPOL_MF_MOVE);
+		TEST_ERRNO = errno;
+		if (ret == -1 && errno == ENOENT)
+			tst_resm(TPASS, "move_pages failed with "
+				 "ENOENT as expected");
+		else
+			tst_resm(TFAIL, "move pages did not fail "
+				 "with ENOENT");
+
+		free_pages(pages, TEST_PAGES);
+	}
+
+	cleanup();
+	/* NOT REACHED */
+
+	return 0;
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+	/* capture signals */
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	check_config(TEST_NODES);
+
+	/* Pause if that option was specified
+	 * TEST_PAUSE contains the code to fork the test with the -c option.
+	 */
+	TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion
+ */
+void
+cleanup(void)
+{
+	/*
+	 * print timing stats if that option was specified.
+	 * print errno log if that option was specified.
+	 */
+	TEST_CLEANUP;
+
+	/* exit with return code appropriate for results */
+	tst_exit();
+	/*NOTREACHED*/
+}
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages11.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages11.c	2008-06-29 22:04:41.000000000 +0530
@@ -0,0 +1,160 @@
+/*
+ *   Copyright (c) 2008 Vijay Kumar B. <vijaykumar@xxxxxxxxxxxx>
+ *
+ *   Based on testcases/kernel/syscalls/waitpid/waitpid01.c
+ *   Original copyright message:
+ *
+ *   Copyright (c) International Business Machines  Corp., 2001
+ *
+ *   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
+ */
+
+/*
+ * NAME
+ *	move_pages11.c
+ *
+ * DESCRIPTION
+ *      Failure when flags passed to move_pages is invalid.
+ *
+ * ALGORITHM
+ *
+ *      1. Pass invalid flag to move_pages().
+ *      2. Check if errno is set to EINVAL.
+ *
+ * USAGE:  <for command-line>
+ *      move_pages11 [-c n] [-i n] [-I x] [-P x] [-t]
+ *      where,  -c n : Run n copies concurrently.
+ *              -i n : Execute test n times.
+ *              -I x : Execute test for x seconds.
+ *              -P x : Pause for x seconds between iterations.
+ *              -t   : Turn on syscall timing.
+ *
+ * History
+ *	05/2008 Vijay Kumar
+ *		Initial Version.
+ *
+ * Restrictions
+ *	None
+ */
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+#include <numa.h>
+
+#include <test.h>
+#include <usctest.h>
+
+#include "move_pages_support.h"
+
+#define TEST_PAGES 2
+#define TEST_NODES 2
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "move_pages11";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+int main(int argc, char **argv)
+{
+	unsigned int i;
+	int lc;				/* loop counter */
+	char *msg;			/* message returned from parse_opts */
+	unsigned int from_node = 0;
+	unsigned int to_node = 1;
+
+	/* parse standard options */
+	msg = parse_opts(argc, argv, (option_t *) NULL, NULL);
+	if (msg != NULL) {
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+		tst_exit();
+		/* NOTREACHED */
+	}
+
+	setup();
+
+	/* check for looping state if -i option is given */
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		void *pages[TEST_PAGES] = { 0 };
+		int nodes[TEST_PAGES];
+		int status[TEST_PAGES];
+		int ret;
+
+		/* reset Tst_count in case we are looping */
+		Tst_count = 0;
+
+		ret = alloc_pages_on_node(pages, TEST_PAGES, from_node);
+		if (ret == -1)
+			continue;
+
+		for (i = 0; i < TEST_PAGES; i++)
+			nodes[i] = to_node;
+
+		ret = numa_move_pages(0, TEST_PAGES, pages, nodes,
+				      status, MPOL_MF_STRICT);
+		TEST_ERRNO = errno;
+		if (ret == -1 && errno == EINVAL)
+			tst_resm(TPASS, "move_pages failed with "
+				 "EINVAL as expected");
+		else
+			tst_resm(TFAIL, "move_pages did not fail "
+				 "with EINVAL");
+
+		free_pages(pages, TEST_PAGES);
+	}
+
+	cleanup();
+	/* NOT REACHED */
+
+	return 0;
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+	/* capture signals */
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	check_config(TEST_NODES);
+
+	/* Pause if that option was specified
+	 * TEST_PAUSE contains the code to fork the test with the -c option.
+	 */
+	TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion
+ */
+void
+cleanup(void)
+{
+	/*
+	 * print timing stats if that option was specified.
+	 * print errno log if that option was specified.
+	 */
+	TEST_CLEANUP;
+
+	/* exit with return code appropriate for results */
+	tst_exit();
+	/*NOTREACHED*/
+}
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages12.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages12.c	2008-06-29 22:04:41.000000000 +0530
@@ -0,0 +1,253 @@
+/*
+ *   Copyright (c) 2008 Vijay Kumar B. <vijaykumar@xxxxxxxxxxxx>
+ *
+ *   Based on testcases/kernel/syscalls/waitpid/waitpid01.c
+ *   Original copyright message:
+ *
+ *   Copyright (c) International Business Machines  Corp., 2001
+ *
+ *   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
+ */
+
+/*
+ * NAME
+ *	move_pages12.c
+ *
+ * DESCRIPTION
+ *      Failure when trying move shared pages.
+ *
+ * ALGORITHM
+ *      1. Allocate a shared memory in NUMA node A.
+ *      2. Fork another process.
+ *      3. Use move_pages() to move the pages to NUMA node B, with the
+ *         MPOL_MF_MOVE_ALL.
+ *      4. Check if errno is set to EPERM.
+ *
+ * USAGE:  <for command-line>
+ *      move_pages12 [-c n] [-i n] [-I x] [-P x] [-t]
+ *      where,  -c n : Run n copies concurrently.
+ *              -i n : Execute test n times.
+ *              -I x : Execute test for x seconds.
+ *              -P x : Pause for x seconds between iterations.
+ *              -t   : Turn on syscall timing.
+ *
+ * History
+ *	05/2008 Vijay Kumar
+ *		Initial Version.
+ *
+ * Restrictions
+ *	None
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <signal.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <numa.h>
+#include <pwd.h>
+
+#include <test.h>
+#include <usctest.h>
+
+#include "move_pages_support.h"
+
+#define TEST_PAGES 2
+#define TEST_NODES 2
+
+enum {
+	SEM_CHILD_SETUP,
+	SEM_PARENT_TEST,
+
+	MAX_SEMS
+};
+
+void setup(void);
+void cleanup(void);
+
+char *TCID = "move_pages12";
+int TST_TOTAL = 1;
+extern int Tst_count;
+
+/*
+ * child() - touches shared pages, and waits for signal from parent.
+ * @pages: shared pages allocated in parent
+ * @sem: semaphore to sync with parent
+ */
+void
+child(void **pages, sem_t *sem)
+{
+	int i;
+
+	for (i = 0; i < TEST_PAGES; i++) {
+		char *page;
+
+		page = pages[i];
+		page[0] = 0xAA;
+	}
+
+	/* Setup complete. Ask parent to continue. */
+	if (sem_post(&sem[SEM_CHILD_SETUP]) == -1)
+		tst_resm(TWARN, "error post semaphore: %s", strerror(errno));
+
+	/* Wait for testcase in parent to complete. */
+	if (sem_wait(&sem[SEM_PARENT_TEST]) == -1)
+		tst_resm(TWARN, "error wait semaphore: %s", strerror(errno));
+
+	exit(0);
+}
+
+int main(int argc, char **argv)
+{
+	unsigned int i;
+	int lc;				/* loop counter */
+	char *msg;			/* message returned from parse_opts */
+	unsigned int from_node = 0;
+	unsigned int to_node = 1;
+
+	/* parse standard options */
+	msg = parse_opts(argc, argv, (option_t *) NULL, NULL);
+	if (msg != NULL) {
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+		tst_exit();
+		/* NOTREACHED */
+	}
+
+	setup();
+
+	/* check for looping state if -i option is given */
+	for (lc = 0; TEST_LOOPING(lc); lc++) {
+		void *pages[TEST_PAGES] = { 0 };
+		int nodes[TEST_PAGES];
+		int status[TEST_PAGES];
+		int ret;
+		pid_t cpid;
+		sem_t *sem;
+
+		/* reset Tst_count in case we are looping */
+		Tst_count = 0;
+
+		ret = alloc_shared_pages_on_node(pages, TEST_PAGES,
+						 from_node);
+		if (ret == -1)
+			continue;
+
+
+		for (i = 0; i < TEST_PAGES; i++) {
+			nodes[i] = to_node;
+		}
+
+		sem = alloc_sem(MAX_SEMS);
+		if (sem == NULL) {
+			goto err_free_pages;
+		}
+
+		/*
+		 * Fork a child process so that the shared pages are
+		 * now really shared between two processes.
+		 */
+		cpid = fork();
+		if (cpid == -1) {
+			tst_resm(TBROK, "forking child failed: %s",
+				 strerror(errno));
+			goto err_free_sem;
+		} else if (cpid == 0) {
+			child(pages, sem);
+		}
+
+		/* Wait for child to setup and signal. */
+		if (sem_wait(&sem[SEM_CHILD_SETUP]) == -1)
+			tst_resm(TWARN, "error wait semaphore: %s",
+				 strerror(errno));
+
+		ret = numa_move_pages(0, TEST_PAGES, pages, nodes,
+				      status, MPOL_MF_MOVE_ALL);
+		TEST_ERRNO = errno;
+		if (ret == -1 && errno == EPERM)
+			tst_resm(TPASS, "move_pages failed with "
+				"EPERM as expected");
+		else
+			tst_resm(TFAIL, "move_pages did not fail "
+				 "with EPERM");
+
+		/* Test done. Ask child to terminate. */
+		if (sem_post(&sem[SEM_PARENT_TEST]) == -1)
+			tst_resm(TWARN, "error post semaphore: %s",
+				 strerror(errno));
+		/* Read the status, no zombies! */
+		wait(NULL);
+	err_free_sem:
+		free_sem(sem, MAX_SEMS);
+	err_free_pages:
+		free_shared_pages(pages, TEST_PAGES);
+	}
+
+	cleanup();
+	/* NOT REACHED */
+
+	return 0;
+}
+
+/*
+ * setup() - performs all ONE TIME setup for this test
+ */
+void
+setup(void)
+{
+	struct passwd *ltpuser;
+
+	/* capture signals */
+	tst_sig(FORK, DEF_HANDLER, cleanup);
+
+	check_config(TEST_NODES);
+
+	if (geteuid() != 0) {
+		tst_resm(TBROK, "test must be run as root");
+		tst_exit();
+	}
+
+	if ((ltpuser = getpwnam("nobody")) == NULL) {
+		tst_resm(TBROK, "'nobody' user not present");
+		tst_exit();
+	}
+
+	if (seteuid(ltpuser->pw_uid) == -1) {
+		tst_resm(TBROK, "setting uid to %d failed", ltpuser->pw_uid);
+		tst_exit();
+	}
+
+	/* Pause if that option was specified
+	 * TEST_PAUSE contains the code to fork the test with the -c option.
+	 */
+	TEST_PAUSE;
+}
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at completion
+ */
+void
+cleanup(void)
+{
+	/*
+	 * print timing stats if that option was specified.
+	 * print errno log if that option was specified.
+	 */
+	TEST_CLEANUP;
+
+	/* exit with return code appropriate for results */
+	tst_exit();
+	/*NOTREACHED*/
+}
Index: ltp-mod/testcases/kernel/syscalls/move_pages/move_pages12.mode.sh
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ ltp-mod/testcases/kernel/syscalls/move_pages/move_pages12.mode.sh	2008-06-29 22:04:41.000000000 +0530
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+failed() {
+	echo ""
+	echo "             ************** WARNING **************"
+	echo "    Cannot change permission or ownership of \"move_pages12\"."
+	echo "                   Test move_pages12 will fail"
+	echo "                   Run "make install" as root."
+	echo "             *************************************"
+	sleep 2
+}
+
+if [ -f move_pages12 ]; then
+    chown root move_pages12 || failed
+    chmod 04755 move_pages12 || failed
+fi
+
+exit 0

--
To unsubscribe from this list: send the line "unsubscribe linux-numa" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]     [Devices]

  Powered by Linux