-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move_pages04: convert to new test API
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
1 parent
57ab216
commit 7685390
Showing
1 changed file
with
110 additions
and
184 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
@@ -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> | ||
|
@@ -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 | ||
|
@@ -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"}, | ||
{} | ||
} | ||
}; |