1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2019 Cyril Hrubis <chrubis@suse.cz> 4f08c3bdfSopenharmony_ci */ 5f08c3bdfSopenharmony_ci 6f08c3bdfSopenharmony_ci/* 7f08c3bdfSopenharmony_ci * We are testing mbind() EIO error. 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * We first fault a allocated page, then attempt to mbind it to a different node. 10f08c3bdfSopenharmony_ci * 11f08c3bdfSopenharmony_ci * This is a regression test for: 12f08c3bdfSopenharmony_ci * 13f08c3bdfSopenharmony_ci * a7f40cfe3b7a mm: mempolicy: make mbind() return -EIO when MPOL_MF_STRICT is specified 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci */ 16f08c3bdfSopenharmony_ci 17f08c3bdfSopenharmony_ci#include <errno.h> 18f08c3bdfSopenharmony_ci#include "config.h" 19f08c3bdfSopenharmony_ci#ifdef HAVE_NUMA_H 20f08c3bdfSopenharmony_ci# include <numa.h> 21f08c3bdfSopenharmony_ci# include <numaif.h> 22f08c3bdfSopenharmony_ci#endif 23f08c3bdfSopenharmony_ci#include "tst_test.h" 24f08c3bdfSopenharmony_ci#include "tst_numa.h" 25f08c3bdfSopenharmony_ci 26f08c3bdfSopenharmony_ci#ifdef HAVE_NUMA_V2 27f08c3bdfSopenharmony_ci 28f08c3bdfSopenharmony_cistatic size_t page_size; 29f08c3bdfSopenharmony_cistatic struct tst_nodemap *nodes; 30f08c3bdfSopenharmony_ci 31f08c3bdfSopenharmony_cistatic void setup(void) 32f08c3bdfSopenharmony_ci{ 33f08c3bdfSopenharmony_ci page_size = getpagesize(); 34f08c3bdfSopenharmony_ci 35f08c3bdfSopenharmony_ci nodes = tst_get_nodemap(TST_NUMA_MEM, 2 * page_size / 1024); 36f08c3bdfSopenharmony_ci if (nodes->cnt <= 1) 37f08c3bdfSopenharmony_ci tst_brk(TCONF, "Test requires at least two NUMA memory nodes"); 38f08c3bdfSopenharmony_ci} 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_cistatic void cleanup(void) 41f08c3bdfSopenharmony_ci{ 42f08c3bdfSopenharmony_ci tst_nodemap_free(nodes); 43f08c3bdfSopenharmony_ci} 44f08c3bdfSopenharmony_ci 45f08c3bdfSopenharmony_cistatic void verify_policy(int mode) 46f08c3bdfSopenharmony_ci{ 47f08c3bdfSopenharmony_ci struct bitmask *bm = numa_allocate_nodemask(); 48f08c3bdfSopenharmony_ci unsigned int i; 49f08c3bdfSopenharmony_ci void *ptr; 50f08c3bdfSopenharmony_ci unsigned long size = page_size; 51f08c3bdfSopenharmony_ci int node = 0; 52f08c3bdfSopenharmony_ci 53f08c3bdfSopenharmony_ci ptr = tst_numa_map(NULL, size); 54f08c3bdfSopenharmony_ci tst_nodemap_reset_counters(nodes); 55f08c3bdfSopenharmony_ci tst_numa_fault(ptr, size); 56f08c3bdfSopenharmony_ci tst_nodemap_count_pages(nodes, ptr, size); 57f08c3bdfSopenharmony_ci tst_nodemap_print_counters(nodes); 58f08c3bdfSopenharmony_ci 59f08c3bdfSopenharmony_ci for (i = 0; i < nodes->cnt; i++) { 60f08c3bdfSopenharmony_ci if (!nodes->counters[i]) { 61f08c3bdfSopenharmony_ci node = nodes->map[i]; 62f08c3bdfSopenharmony_ci tst_res(TINFO, "Attempting to bind to node %i", node); 63f08c3bdfSopenharmony_ci numa_bitmask_setbit(bm, node); 64f08c3bdfSopenharmony_ci break; 65f08c3bdfSopenharmony_ci } 66f08c3bdfSopenharmony_ci } 67f08c3bdfSopenharmony_ci 68f08c3bdfSopenharmony_ci TEST(mbind(ptr, size, mode, bm->maskp, bm->size + 1, MPOL_MF_STRICT)); 69f08c3bdfSopenharmony_ci 70f08c3bdfSopenharmony_ci tst_numa_unmap(ptr, size); 71f08c3bdfSopenharmony_ci numa_free_nodemask(bm); 72f08c3bdfSopenharmony_ci 73f08c3bdfSopenharmony_ci if (TST_RET != -1) { 74f08c3bdfSopenharmony_ci tst_res(TFAIL, 75f08c3bdfSopenharmony_ci "mbind(%s, MPOL_MF_STRICT) node %u returned %li, expected -1", 76f08c3bdfSopenharmony_ci tst_mempolicy_mode_name(mode), node, TST_RET); 77f08c3bdfSopenharmony_ci return; 78f08c3bdfSopenharmony_ci } 79f08c3bdfSopenharmony_ci 80f08c3bdfSopenharmony_ci if (TST_ERR == EIO) { 81f08c3bdfSopenharmony_ci tst_res(TPASS | TTERRNO, 82f08c3bdfSopenharmony_ci "mbind(%s, MPOL_MF_STRICT) node %u", 83f08c3bdfSopenharmony_ci tst_mempolicy_mode_name(mode), node); 84f08c3bdfSopenharmony_ci } else { 85f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, 86f08c3bdfSopenharmony_ci "mbind(%s, MPOL_MF_STRICT) node %u expected EIO", 87f08c3bdfSopenharmony_ci tst_mempolicy_mode_name(mode), node); 88f08c3bdfSopenharmony_ci } 89f08c3bdfSopenharmony_ci} 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_cistatic const int modes[] = { 92f08c3bdfSopenharmony_ci MPOL_PREFERRED, 93f08c3bdfSopenharmony_ci MPOL_BIND, 94f08c3bdfSopenharmony_ci MPOL_INTERLEAVE, 95f08c3bdfSopenharmony_ci}; 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_cistatic void verify_mbind(unsigned int n) 98f08c3bdfSopenharmony_ci{ 99f08c3bdfSopenharmony_ci verify_policy(modes[n]); 100f08c3bdfSopenharmony_ci} 101f08c3bdfSopenharmony_ci 102f08c3bdfSopenharmony_cistatic struct tst_test test = { 103f08c3bdfSopenharmony_ci .setup = setup, 104f08c3bdfSopenharmony_ci .cleanup = cleanup, 105f08c3bdfSopenharmony_ci .test = verify_mbind, 106f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(modes), 107f08c3bdfSopenharmony_ci .tags = (const struct tst_tag[]) { 108f08c3bdfSopenharmony_ci {"linux-git", "a7f40cfe3b7a"}, 109f08c3bdfSopenharmony_ci {} 110f08c3bdfSopenharmony_ci } 111f08c3bdfSopenharmony_ci}; 112f08c3bdfSopenharmony_ci 113f08c3bdfSopenharmony_ci#else 114f08c3bdfSopenharmony_ci 115f08c3bdfSopenharmony_ciTST_TEST_TCONF(NUMA_ERROR_MSG); 116f08c3bdfSopenharmony_ci 117f08c3bdfSopenharmony_ci#endif /* HAVE_NUMA_H */ 118