Skip to content

Commit

Permalink
move_pages04: convert to new test API
Browse files Browse the repository at this point in the history
Let's convert the test to the new test API and cleanup the file header
a bit.

It's worth nothing that the "-c", "-P" and "-t" options are were not
working although documented.

Signed-off-by: David Hildenbrand <[email protected]>
Suggested-by: Cyril Hrubis <[email protected]>
Reviewed-by: Jan Stancek <[email protected]>
Reviewed-by: Cyril Hrubis <[email protected]>
  • Loading branch information
davidhildenbrand authored and metan-ucw committed Oct 17, 2024
1 parent 57ab216 commit 7685390
Showing 1 changed file with 110 additions and 184 deletions.
294 changes: 110 additions & 184 deletions testcases/kernel/syscalls/move_pages/move_pages04.c
Original file line number Diff line number Diff line change
@@ -1,35 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2008 Vijay Kumar B. <[email protected]>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

/*
* NAME
* move_pages04.c
/*\
* [Description]
*
* DESCRIPTION
* Failure when the memory area is not valid, no page is mapped yet or
* the shared zero page is mapped.
* Verify that move_pages() properly reports failures when the memory area is
* not valid, no page is mapped yet or the shared zero page is mapped.
*
* ALGORITHM
* [Algorithm]
*
* 1. Pass the address of a valid memory area where no page is
* mapped yet (not read/written), the address of a valid memory area
Expand All @@ -44,25 +25,8 @@
* 4. Check if the corresponding status for "invalid memory area" is set
* to -EFAULT.
*
* [1]
* d899844e9c98 "mm: fix status code which move_pages() returns for zero page"
* [2]
* 7dff875c9436 "mm/migrate: convert add_page_for_migration() from follow_page() to folio_walk"
*
* 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
* [1] d899844e9c98 "mm: fix status code which move_pages() returns for zero page"
* [2] 7dff875c9436 "mm/migrate: convert add_page_for_migration() from follow_page() to folio_walk"
*/

#include <sys/mman.h>
Expand All @@ -71,7 +35,7 @@
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include "test.h"
#include "tst_test.h"
#include "move_pages_support.h"

#define TEST_PAGES 4
Expand All @@ -81,162 +45,124 @@
#define ZERO_PAGE (NO_PAGE + 1)
#define INVALID_PAGE (ZERO_PAGE + 1)

void setup(void);
void cleanup(void);

char *TCID = "move_pages04";
int TST_TOTAL = 1;

typedef void (*sighandler_t) (int);

int main(int argc, char **argv)
static void run(void)
{

tst_parse_opts(argc, argv, NULL, NULL);

setup();

#ifdef HAVE_NUMA_V2
unsigned int i;
int lc;
unsigned int from_node;
unsigned int to_node;
int ret;
void *pages[TEST_PAGES] = { 0 };
int nodes[TEST_PAGES];
int status[TEST_PAGES];
unsigned long onepage = get_page_size();
char tmp;

ret = get_allowed_nodes(NH_MEMS, 2, &from_node, &to_node);
if (ret < 0)
tst_brkm(TBROK | TERRNO, cleanup, "get_allowed_nodes: %d", ret);

/* 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];
unsigned long onepage = get_page_size();
char tmp;

/* 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 memory and do not touch it. Consequently, no
* page will be faulted in / mapped into the page tables.
*/
pages[NO_PAGE] = numa_alloc_onnode(onepage, from_node);
if (pages[NO_PAGE] == NULL) {
tst_resm(TBROK, "failed allocating memory on node %d",
from_node);
goto err_free_pages;
}

/*
* Allocate memory, read from it, but do not write to it. This
* will populate the shared zeropage.
*/
pages[ZERO_PAGE] = numa_alloc_onnode(onepage, from_node);
if (pages[ZERO_PAGE] == NULL) {
tst_resm(TBROK, "failed allocating memory on node %d",
from_node);
goto err_free_pages;
}
/* Make the compiler not optimize-out the read. */
tmp = *((char *)pages[ZERO_PAGE]);
asm volatile("" : "+r" (tmp));

/*
* Temporarily allocate memory and free it immediately. Do this
* as the last step so the area won't get reused before we're
* done.
*/
pages[INVALID_PAGE] = numa_alloc_onnode(onepage, from_node);
if (pages[INVALID_PAGE] == NULL) {
tst_resm(TBROK, "failed allocating memory on node %d",
from_node);
goto err_free_pages;
}
numa_free(pages[INVALID_PAGE], onepage);

for (i = 0; i < TEST_PAGES; i++)
nodes[i] = to_node;

ret = numa_move_pages(0, TEST_PAGES, pages, nodes,
status, MPOL_MF_MOVE);
if (ret == -1) {
tst_resm(TFAIL | TERRNO,
"move_pages unexpectedly failed");
goto err_free_pages;
} else if (ret > 0) {
tst_resm(TINFO, "move_pages() returned %d", ret);
}

if (status[NO_PAGE] == -ENOENT) {
tst_resm(TPASS, "status[%d] has expected value",
NO_PAGE);
} else {
tst_resm(TFAIL, "status[%d] is %s, expected %s",
NO_PAGE,
tst_strerrno(-status[NO_PAGE]),
tst_strerrno(ENOENT));
}

if (status[ZERO_PAGE] == -EFAULT) {
tst_resm(TPASS, "status[%d] has expected value",
ZERO_PAGE);
} else {
tst_resm(TFAIL, "status[%d] is %s, expected %s",
ZERO_PAGE,
tst_strerrno(-status[ZERO_PAGE]),
tst_strerrno(EFAULT));
}

if (status[INVALID_PAGE] == -EFAULT) {
tst_resm(TPASS, "status[%d] has expected value",
INVALID_PAGE);
} else {
tst_resm(TFAIL, "status[%d] is %s, expected %s",
INVALID_PAGE,
tst_strerrno(-status[INVALID_PAGE]),
tst_strerrno(EFAULT));
}
tst_brk(TBROK | TERRNO, "get_allowed_nodes: %d", ret);

err_free_pages:
/* Memory for the invalid page was already freed. */
pages[INVALID_PAGE] = NULL;
/* This is capable of freeing all memory we allocated. */
free_pages(pages, TEST_PAGES);
ret = alloc_pages_on_node(pages, TOUCHED_PAGES, from_node);
if (ret == -1)
tst_brk(TBROK, "failed allocating memory on node %d",
from_node);

/*
* Allocate memory and do not touch it. Consequently, no
* page will be faulted in / mapped into the page tables.
*/
pages[NO_PAGE] = numa_alloc_onnode(onepage, from_node);
if (pages[NO_PAGE] == NULL)
tst_brk(TBROK, "failed allocating memory on node %d",
from_node);

/*
* Allocate memory, read from it, but do not write to it. This
* will populate the shared zeropage.
*/
pages[ZERO_PAGE] = numa_alloc_onnode(onepage, from_node);
if (pages[ZERO_PAGE] == NULL)
tst_brk(TBROK, "failed allocating memory on node %d",
from_node);
/* Make the compiler not optimize-out the read. */
tmp = *((char *)pages[ZERO_PAGE]);
asm volatile("" : "+r" (tmp));

/*
* Temporarily allocate memory and free it immediately. Do this
* as the last step so the area won't get reused before we're
* done.
*/
pages[INVALID_PAGE] = numa_alloc_onnode(onepage, from_node);
if (pages[INVALID_PAGE] == NULL)
tst_brk(TBROK, "failed allocating memory on node %d",
from_node);
numa_free(pages[INVALID_PAGE], onepage);

for (i = 0; i < TEST_PAGES; i++)
nodes[i] = to_node;

ret = numa_move_pages(0, TEST_PAGES, pages, nodes,
status, MPOL_MF_MOVE);
if (ret == -1) {
tst_res(TFAIL | TERRNO,
"move_pages unexpectedly failed");
goto err_free_pages;
} else if (ret > 0) {
tst_res(TINFO, "move_pages() returned %d", ret);
}

if (status[NO_PAGE] == -ENOENT) {
tst_res(TPASS, "status[%d] has expected value",
NO_PAGE);
} else {
tst_res(TFAIL, "status[%d] is %s, expected %s",
NO_PAGE,
tst_strerrno(-status[NO_PAGE]),
tst_strerrno(ENOENT));
}

if (status[ZERO_PAGE] == -EFAULT) {
tst_res(TPASS, "status[%d] has expected value",
ZERO_PAGE);
} else {
tst_res(TFAIL, "status[%d] is %s, expected %s",
ZERO_PAGE,
tst_strerrno(-status[ZERO_PAGE]),
tst_strerrno(EFAULT));
}

if (status[INVALID_PAGE] == -EFAULT) {
tst_res(TPASS, "status[%d] has expected value",
INVALID_PAGE);
} else {
tst_res(TFAIL, "status[%d] is %s, expected %s",
INVALID_PAGE,
tst_strerrno(-status[INVALID_PAGE]),
tst_strerrno(EFAULT));
}

err_free_pages:
/* Memory for the invalid page was already freed. */
pages[INVALID_PAGE] = NULL;
/* This is capable of freeing all memory we allocated. */
free_pages(pages, TEST_PAGES);
#else
tst_resm(TCONF, NUMA_ERROR_MSG);
tst_res(TCONF, NUMA_ERROR_MSG);
#endif

cleanup();
tst_exit();
}

/*
* setup() - performs all ONE TIME setup for this test
*/
void setup(void)
{

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)
{

}
static struct tst_test test = {
.test_all = run,
.setup = setup,
.tags = (const struct tst_tag[]) {
{"linux-git", "d899844e9c98"},
{"linux-git", "7dff875c9436"},
{}
}
};

0 comments on commit 7685390

Please sign in to comment.