From 83bbb87a0f0287f257b0e55ffb4ab6bd1bbdaa35 Mon Sep 17 00:00:00 2001 From: Ken Sato Date: Thu, 16 Jan 2020 11:33:55 +0900 Subject: [PATCH] mbind: fix processing when new range ovarlaps existing range(s) Change-Id: I240a0205f0d836e4ff1a16b6739a3b366543bc06 Refs: #1384 --- kernel/syscall.c | 169 ++++++++++++++++++++-------- test/issues/1384/C1384.h | 11 ++ test/issues/1384/C1384.sh | 41 +++++++ test/issues/1384/C1384T01.c | 90 +++++++++++++++ test/issues/1384/C1384T02.c | 90 +++++++++++++++ test/issues/1384/C1384T03.c | 90 +++++++++++++++ test/issues/1384/C1384T04.c | 90 +++++++++++++++ test/issues/1384/C1384T05.c | 104 +++++++++++++++++ test/issues/1384/C1384T06.c | 104 +++++++++++++++++ test/issues/1384/Makefile | 11 ++ test/issues/1384/README | 30 +++++ test/issues/1384/aarch64_result.log | 127 +++++++++++++++++++++ test/issues/1384/x86_64_result.log | 127 +++++++++++++++++++++ 13 files changed, 1038 insertions(+), 46 deletions(-) create mode 100644 test/issues/1384/C1384.h create mode 100755 test/issues/1384/C1384.sh create mode 100644 test/issues/1384/C1384T01.c create mode 100644 test/issues/1384/C1384T02.c create mode 100644 test/issues/1384/C1384T03.c create mode 100644 test/issues/1384/C1384T04.c create mode 100644 test/issues/1384/C1384T05.c create mode 100644 test/issues/1384/C1384T06.c create mode 100644 test/issues/1384/Makefile create mode 100644 test/issues/1384/README create mode 100644 test/issues/1384/aarch64_result.log create mode 100644 test/issues/1384/x86_64_result.log diff --git a/kernel/syscall.c b/kernel/syscall.c index d8fbf654..e677e3f0 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -4378,29 +4378,35 @@ struct vm_range_numa_policy *vm_range_policy_search(struct process_vm *vm, uintp return NULL; } -static int vm_policy_insert(struct process_vm *vm, struct vm_range_numa_policy *newrange) +static int vm_policy_insert(struct process_vm *vm, + struct vm_range_numa_policy *newrange) { struct rb_root *root = &vm->vm_range_numa_policy_tree; struct rb_node **new = &(root->rb_node), *parent = NULL; struct vm_range_numa_policy *range; while (*new) { - range = rb_entry(*new, struct vm_range_numa_policy, policy_rb_node); + range = rb_entry(*new, struct vm_range_numa_policy, + policy_rb_node); parent = *new; if (newrange->end <= range->start) { new = &((*new)->rb_left); } else if (newrange->start >= range->end) { new = &((*new)->rb_right); } else { - ekprintf("vm_range_insert(%p,%lx-%lx (nodemask)%lx (policy)%d): overlap %lx-%lx (nodemask)%lx (policy)%d\n", - vm, newrange->start, newrange->end, newrange->numa_mask, newrange->numa_mem_policy, - range->start, range->end, range->numa_mask, range->numa_mem_policy); + ekprintf("%s(%p,%lx-%lx (nodemask)%lx (policy)%d): overlap %lx-%lx (nodemask)%lx (policy)%d\n", + __func__, vm, newrange->start, + newrange->end, newrange->numa_mask, + newrange->numa_mem_policy, range->start, + range->end, range->numa_mask, + range->numa_mem_policy); return -EFAULT; } } - dkprintf("vm_range_insert: %p,%p: %lx-%lx (nodemask)%lx (policy)%d\n", - vm, newrange, newrange->start, newrange->end, newrange->numa_mask, newrange->numa_mem_policy); + dkprintf("%s: %p,%p: %lx-%lx (nodemask)%lx (policy)%d\n", + __func__, vm, newrange, newrange->start, newrange->end, + newrange->numa_mask, newrange->numa_mem_policy); rb_link_node(&newrange->policy_rb_node, parent, new); rb_insert_color(&newrange->policy_rb_node, root); @@ -4408,6 +4414,106 @@ static int vm_policy_insert(struct process_vm *vm, struct vm_range_numa_policy * return 0; } +static int vm_policy_clear_range(struct process_vm *vm, + unsigned long start, unsigned long end) +{ + struct rb_root *root = &vm->vm_range_numa_policy_tree; + struct vm_range_numa_policy *range, *range_policy_iter; + struct vm_range_numa_policy *range_policy; + struct rb_node *node; + int error = 0; + + /* + * Adjust overlapping range settings and add new one + * case: front part of new range overlaps existing one + * case: new range is a part of existing range + */ + range_policy_iter = vm_range_policy_search(vm, start); + if (range_policy_iter) { + int adjusted = 0; + unsigned long orig_end = range_policy_iter->end; + + if (range_policy_iter->start == start && + range_policy_iter->end == end) { + rb_erase(&range_policy_iter->policy_rb_node, + &vm->vm_range_numa_policy_tree); + kfree(range_policy_iter); + error = 0; + goto out; + } + + /* Overlapping partially? */ + if (range_policy_iter->start < start) { + orig_end = range_policy_iter->end; + range_policy_iter->end = start; + adjusted = 1; + } + + /* Do we need to keep the end? */ + if (orig_end > end) { + if (adjusted) { + /* Add a new entry after */ + range_policy = kmalloc( + sizeof(struct vm_range_numa_policy), + IHK_MC_AP_NOWAIT); + if (!range_policy) { + dkprintf("%s: error allocating range_policy\n", + __func__); + error = -ENOMEM; + goto out; + } + + RB_CLEAR_NODE(&range_policy->policy_rb_node); + range_policy->start = end; + range_policy->end = orig_end; + range_policy->numa_mem_policy = + range_policy_iter->numa_mem_policy; + + memcpy(range_policy->numa_mask, + &range_policy_iter->numa_mask, + sizeof(range_policy->numa_mask)); + + error = vm_policy_insert(vm, range_policy); + if (error) { + kprintf("%s: ERROR: could not insert range: %d\n", + __func__, error); + goto out; + } + } + else { + range_policy_iter->start = end; + } + } + } + + /* + * Adjust overlapping range settings + * case: rear part of new range overlaps existing range + */ + range_policy_iter = vm_range_policy_search(vm, end - 1); + if (range_policy_iter) { + range_policy_iter->start = end; + } + + /* Search fulliy contained range */ +again_search: + for (node = rb_first(root); node; node = rb_next(node)) { + range = rb_entry(node, struct vm_range_numa_policy, + policy_rb_node); + + /* existing range is fully contained */ + if (range->start >= start && range->end <= end) { + rb_erase(&range->policy_rb_node, + &vm->vm_range_numa_policy_tree); + kfree(range); + goto again_search; + } + } + +out: + return error; +} + #ifdef ENABLE_PERF static int mc_perf_event_alloc(struct mc_perf_event **out, struct perf_event_attr *attr) @@ -8838,52 +8944,23 @@ SYSCALL_DECLARE(mbind) case MPOL_BIND: case MPOL_INTERLEAVE: case MPOL_PREFERRED: - /* Adjust any overlapping range settings and add new one */ + /* Check if same range is existing */ range_policy_iter = vm_range_policy_search(vm, addr); if (range_policy_iter) { - int adjusted = 0; - unsigned long orig_end = range_policy_iter->end; - if (range_policy_iter->start == addr && - range_policy_iter->end == addr + len) { + range_policy_iter->end == addr + len) { + /* same range */ range_policy = range_policy_iter; goto mbind_update_only; } + } - /* Overlapping partially? */ - if (range_policy_iter->start < addr) { - orig_end = range_policy_iter->end; - range_policy_iter->end = addr; - adjusted = 1; - } - - /* Do we need to keep the end? */ - if (orig_end > addr + len) { - if (adjusted) { - /* Add a new entry after */ - range_policy = kmalloc(sizeof(struct vm_range_numa_policy), - IHK_MC_AP_NOWAIT); - if (!range_policy) { - dkprintf("%s: error allocating range_policy\n", - __FUNCTION__); - error = -ENOMEM; - goto unlock_out; - } - - RB_CLEAR_NODE(&range_policy->policy_rb_node); - range_policy->start = addr + len; - range_policy->end = orig_end; - - error = vm_policy_insert(vm, range_policy); - if (error) { - kprintf("%s: ERROR: could not insert range: %d\n",__FUNCTION__, error); - goto unlock_out; - } - } - else { - range_policy_iter->start = addr + len; - } - } + /* Clear target range */ + error = vm_policy_clear_range(vm, addr, addr + len); + if (error) { + ekprintf("%s: ERROR: clear policy_range\n", + __func__); + goto unlock_out; } /* Add a new entry */ diff --git a/test/issues/1384/C1384.h b/test/issues/1384/C1384.h new file mode 100644 index 00000000..9569bf63 --- /dev/null +++ b/test/issues/1384/C1384.h @@ -0,0 +1,11 @@ +#include +#include + +#define M_B MPOL_BIND +#define M_D MPOL_DEFAULT + +struct mbind_info { + int offset; + int size; + int policy; +}; diff --git a/test/issues/1384/C1384.sh b/test/issues/1384/C1384.sh new file mode 100755 index 00000000..ee34bf22 --- /dev/null +++ b/test/issues/1384/C1384.sh @@ -0,0 +1,41 @@ +#/bin/sh + +USELTP=1 +USEOSTEST=0 + +. ../../common.sh + +issue="1384" +tid=01 + +for tno in 01 02 03 04 05 06 +do + tname=`printf "C${issue}T%02d" ${tid}` + echo "*** ${tname} start *******************************" + sudo ${MCEXEC} ./C1384T${tno} + + if [ $? -eq 0 ]; then + echo "*** ${tname} PASSED ******************************" + else + echo "*** ${tname} FAILED ******************************" + fi + let tid++ + echo "" +done + +for tp in vma02 mbind01 get_mempolicy01 +do + tname=`printf "C${issue}T%02d" ${tid}` + echo "*** ${tname} start *******************************" + sudo $MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt + ok=`grep PASS $tp.txt | wc -l` + ng=`grep FAIL $tp.txt | wc -l` + if [ $ng = 0 ]; then + echo "*** ${tname} PASSED ($ok)" + else + echo "*** ${tname} FAILED (ok=$ok ng=$ng)" + fi + let tid++ + echo "" +done + diff --git a/test/issues/1384/C1384T01.c b/test/issues/1384/C1384T01.c new file mode 100644 index 00000000..bcd001c9 --- /dev/null +++ b/test/issues/1384/C1384T01.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "./C1384.h" + +#define PAGES 5 + +static unsigned long pagesize; + +struct mbind_info base = {1, 3, MPOL_BIND}; +struct mbind_info new = {0, 3, MPOL_DEFAULT}; +static int expect_policies[PAGES] = {M_D, M_D, M_D, M_B, M_D}; + +int main(int argc, char **argv) +{ + void *addr; + int i, node, err, policy, ret = 0; + unsigned long base_start, base_size, new_start, new_size; + struct bitmask *nmask = numa_allocate_nodemask(); + + pagesize = getpagesize(); + node = 1; + + numa_bitmask_setbit(nmask, node); + + addr = mmap(NULL, pagesize * PAGES, PROT_WRITE, + MAP_ANON | MAP_PRIVATE, 0, 0); + if (addr == MAP_FAILED) { + perror("mmap faile: "); + ret = -1; + goto out; + } + + /* make page populate */ + memset(addr, 0, pagesize * PAGES); + + /* base mbind */ + base_start = (unsigned long)addr + pagesize * base.offset; + base_size = pagesize * base.size; + err = mbind((void *)base_start, base_size, base.policy, nmask->maskp, + nmask->size, MPOL_MF_MOVE_ALL); + if (err != 0) { + perror("base mbind fail: "); + ret = -1; + goto out; + } + printf("base mbind: 0x%lx - 0x%lx policy:%d\n", + base_start, base_start + base_size, base.policy); + + /* new mbind */ + new_start = (unsigned long)addr + pagesize * new.offset; + new_size = pagesize * new.size; + err = mbind((void *)new_start, new_size, new.policy, + NULL, 0, 0); + if (err != 0) { + perror("new mbind fail: "); + ret = -1; + goto out; + } + printf("new mbind: 0x%lx - 0x%lx policy:%d\n", + new_start, new_start + new_size, new.policy); + + for (i = 0; i < PAGES; i++) { + err = get_mempolicy(&policy, nmask->maskp, nmask->size, + addr + pagesize * i, MPOL_F_ADDR); + if (err != 0) { + perror("get_mempolicy fail: "); + ret = -1; + goto out; + } + + if (policy != expect_policies[i]) { + printf("[NG] policy[%d] is %d (expected %d)\n", + i, policy, expect_policies[i]); + ret = -1; + goto out; + } + } + + printf("[OK] policies are expected\n"); +out: + return ret; +} diff --git a/test/issues/1384/C1384T02.c b/test/issues/1384/C1384T02.c new file mode 100644 index 00000000..c39427fc --- /dev/null +++ b/test/issues/1384/C1384T02.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "./C1384.h" + +#define PAGES 5 + +static unsigned long pagesize; + +struct mbind_info base = {1, 3, MPOL_BIND}; +struct mbind_info new = {1, 3, MPOL_DEFAULT}; +static int expect_policies[PAGES] = {M_D, M_D, M_D, M_D, M_D}; + +int main(int argc, char **argv) +{ + void *addr; + int i, node, err, policy, ret = 0; + unsigned long base_start, base_size, new_start, new_size; + struct bitmask *nmask = numa_allocate_nodemask(); + + pagesize = getpagesize(); + node = 1; + + numa_bitmask_setbit(nmask, node); + + addr = mmap(NULL, pagesize * PAGES, PROT_WRITE, + MAP_ANON | MAP_PRIVATE, 0, 0); + if (addr == MAP_FAILED) { + perror("mmap faile: "); + ret = -1; + goto out; + } + + /* make page populate */ + memset(addr, 0, pagesize * PAGES); + + /* base mbind */ + base_start = (unsigned long)addr + pagesize * base.offset; + base_size = pagesize * base.size; + err = mbind((void *)base_start, base_size, base.policy, nmask->maskp, + nmask->size, MPOL_MF_MOVE_ALL); + if (err != 0) { + perror("base mbind fail: "); + ret = -1; + goto out; + } + printf("base mbind: 0x%lx - 0x%lx policy:%d\n", + base_start, base_start + base_size, base.policy); + + /* new mbind */ + new_start = (unsigned long)addr + pagesize * new.offset; + new_size = pagesize * new.size; + err = mbind((void *)new_start, new_size, new.policy, + NULL, 0, 0); + if (err != 0) { + perror("new mbind fail: "); + ret = -1; + goto out; + } + printf("new mbind: 0x%lx - 0x%lx policy:%d\n", + new_start, new_start + new_size, new.policy); + + for (i = 0; i < PAGES; i++) { + err = get_mempolicy(&policy, nmask->maskp, nmask->size, + addr + pagesize * i, MPOL_F_ADDR); + if (err != 0) { + perror("get_mempolicy fail: "); + ret = -1; + goto out; + } + + if (policy != expect_policies[i]) { + printf("[NG] policy[%d] is %d (expected %d)\n", + i, policy, expect_policies[i]); + ret = -1; + goto out; + } + } + + printf("[OK] policies are expected\n"); +out: + return ret; +} diff --git a/test/issues/1384/C1384T03.c b/test/issues/1384/C1384T03.c new file mode 100644 index 00000000..257c3d09 --- /dev/null +++ b/test/issues/1384/C1384T03.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "./C1384.h" + +#define PAGES 5 + +static unsigned long pagesize; + +struct mbind_info base = {0, 5, MPOL_BIND}; +struct mbind_info new = {1, 3, MPOL_DEFAULT}; +static int expect_policies[PAGES] = {M_B, M_D, M_D, M_D, M_B}; + +int main(int argc, char **argv) +{ + void *addr; + int i, node, err, policy, ret = 0; + unsigned long base_start, base_size, new_start, new_size; + struct bitmask *nmask = numa_allocate_nodemask(); + + pagesize = getpagesize(); + node = 1; + + numa_bitmask_setbit(nmask, node); + + addr = mmap(NULL, pagesize * PAGES, PROT_WRITE, + MAP_ANON | MAP_PRIVATE, 0, 0); + if (addr == MAP_FAILED) { + perror("mmap faile: "); + ret = -1; + goto out; + } + + /* make page populate */ + memset(addr, 0, pagesize * PAGES); + + /* base mbind */ + base_start = (unsigned long)addr + pagesize * base.offset; + base_size = pagesize * base.size; + err = mbind((void *)base_start, base_size, base.policy, nmask->maskp, + nmask->size, MPOL_MF_MOVE_ALL); + if (err != 0) { + perror("base mbind fail: "); + ret = -1; + goto out; + } + printf("base mbind: 0x%lx - 0x%lx policy:%d\n", + base_start, base_start + base_size, base.policy); + + /* new mbind */ + new_start = (unsigned long)addr + pagesize * new.offset; + new_size = pagesize * new.size; + err = mbind((void *)new_start, new_size, new.policy, + NULL, 0, 0); + if (err != 0) { + perror("new mbind fail: "); + ret = -1; + goto out; + } + printf("new mbind: 0x%lx - 0x%lx policy:%d\n", + new_start, new_start + new_size, new.policy); + + for (i = 0; i < PAGES; i++) { + err = get_mempolicy(&policy, nmask->maskp, nmask->size, + addr + pagesize * i, MPOL_F_ADDR); + if (err != 0) { + perror("get_mempolicy fail: "); + ret = -1; + goto out; + } + + if (policy != expect_policies[i]) { + printf("[NG] policy[%d] is %d (expected %d)\n", + i, policy, expect_policies[i]); + ret = -1; + goto out; + } + } + + printf("[OK] policies are expected\n"); +out: + return ret; +} diff --git a/test/issues/1384/C1384T04.c b/test/issues/1384/C1384T04.c new file mode 100644 index 00000000..67332f09 --- /dev/null +++ b/test/issues/1384/C1384T04.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "./C1384.h" + +#define PAGES 5 + +static unsigned long pagesize; + +struct mbind_info base = {1, 3, MPOL_BIND}; +struct mbind_info new = {2, 3, MPOL_DEFAULT}; +static int expect_policies[PAGES] = {M_D, M_B, M_D, M_D, M_D}; + +int main(int argc, char **argv) +{ + void *addr; + int i, node, err, policy, ret = 0; + unsigned long base_start, base_size, new_start, new_size; + struct bitmask *nmask = numa_allocate_nodemask(); + + pagesize = getpagesize(); + node = 1; + + numa_bitmask_setbit(nmask, node); + + addr = mmap(NULL, pagesize * PAGES, PROT_WRITE, + MAP_ANON | MAP_PRIVATE, 0, 0); + if (addr == MAP_FAILED) { + perror("mmap faile: "); + ret = -1; + goto out; + } + + /* make page populate */ + memset(addr, 0, pagesize * PAGES); + + /* base mbind */ + base_start = (unsigned long)addr + pagesize * base.offset; + base_size = pagesize * base.size; + err = mbind((void *)base_start, base_size, base.policy, nmask->maskp, + nmask->size, MPOL_MF_MOVE_ALL); + if (err != 0) { + perror("base mbind fail: "); + ret = -1; + goto out; + } + printf("base mbind: 0x%lx - 0x%lx policy:%d\n", + base_start, base_start + base_size, base.policy); + + /* new mbind */ + new_start = (unsigned long)addr + pagesize * new.offset; + new_size = pagesize * new.size; + err = mbind((void *)new_start, new_size, new.policy, + NULL, 0, 0); + if (err != 0) { + perror("new mbind fail: "); + ret = -1; + goto out; + } + printf("new mbind: 0x%lx - 0x%lx policy:%d\n", + new_start, new_start + new_size, new.policy); + + for (i = 0; i < PAGES; i++) { + err = get_mempolicy(&policy, nmask->maskp, nmask->size, + addr + pagesize * i, MPOL_F_ADDR); + if (err != 0) { + perror("get_mempolicy fail: "); + ret = -1; + goto out; + } + + if (policy != expect_policies[i]) { + printf("[NG] policy[%d] is %d (expected %d)\n", + i, policy, expect_policies[i]); + ret = -1; + goto out; + } + } + + printf("[OK] policies are expected\n"); +out: + return ret; +} diff --git a/test/issues/1384/C1384T05.c b/test/issues/1384/C1384T05.c new file mode 100644 index 00000000..594fc887 --- /dev/null +++ b/test/issues/1384/C1384T05.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "./C1384.h" + +#define PAGES 5 + +static unsigned long pagesize; + +struct mbind_info base1 = {1, 1, MPOL_BIND}; +struct mbind_info base2 = {1, 3, MPOL_BIND}; +struct mbind_info new = {0, 5, MPOL_DEFAULT}; +static int expect_policies[PAGES] = {M_D, M_D, M_D, M_D, M_D}; + +int main(int argc, char **argv) +{ + void *addr; + int i, node, err, policy, ret = 0; + unsigned long base_start, base_size, new_start, new_size; + struct bitmask *nmask = numa_allocate_nodemask(); + + pagesize = getpagesize(); + node = 1; + + numa_bitmask_setbit(nmask, node); + + addr = mmap(NULL, pagesize * PAGES, PROT_WRITE, + MAP_ANON | MAP_PRIVATE, 0, 0); + if (addr == MAP_FAILED) { + perror("mmap faile: "); + ret = -1; + goto out; + } + + /* make page populate */ + memset(addr, 0, pagesize * PAGES); + + /* base1 mbind */ + base_start = (unsigned long)addr + pagesize * base1.offset; + base_size = pagesize * base1.size; + err = mbind((void *)base_start, base_size, base1.policy, nmask->maskp, + nmask->size, MPOL_MF_MOVE_ALL); + if (err != 0) { + perror("base1 mbind fail: "); + ret = -1; + goto out; + } + printf("base1 mbind: 0x%lx - 0x%lx policy:%d\n", + base_start, base_start + base_size, base1.policy); + + /* base2 mbind */ + base_start = (unsigned long)addr + pagesize * base2.offset; + base_size = pagesize * base2.size; + err = mbind((void *)base_start, base_size, base2.policy, nmask->maskp, + nmask->size, MPOL_MF_MOVE_ALL); + if (err != 0) { + perror("base2 mbind fail: "); + ret = -1; + goto out; + } + printf("base2 mbind: 0x%lx - 0x%lx policy:%d\n", + base_start, base_start + base_size, base2.policy); + + /* new mbind */ + new_start = (unsigned long)addr + pagesize * new.offset; + new_size = pagesize * new.size; + err = mbind((void *)new_start, new_size, new.policy, + NULL, 0, 0); + if (err != 0) { + perror("new mbind fail: "); + ret = -1; + goto out; + } + printf("new mbind: 0x%lx - 0x%lx policy:%d\n", + new_start, new_start + new_size, new.policy); + + for (i = 0; i < PAGES; i++) { + err = get_mempolicy(&policy, nmask->maskp, nmask->size, + addr + pagesize * i, MPOL_F_ADDR); + if (err != 0) { + perror("get_mempolicy fail: "); + ret = -1; + goto out; + } + + if (policy != expect_policies[i]) { + printf("[NG] policy[%d] is %d (expected %d)\n", + i, policy, expect_policies[i]); + ret = -1; + goto out; + } + } + + printf("[OK] policies are expected\n"); +out: + return ret; +} diff --git a/test/issues/1384/C1384T06.c b/test/issues/1384/C1384T06.c new file mode 100644 index 00000000..5c36f358 --- /dev/null +++ b/test/issues/1384/C1384T06.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "./C1384.h" + +#define PAGES 5 + +static unsigned long pagesize; + +struct mbind_info base1 = {0, 3, MPOL_BIND}; +struct mbind_info base2 = {3, 2, MPOL_BIND}; +struct mbind_info new = {1, 3, MPOL_DEFAULT}; +static int expect_policies[PAGES] = {M_B, M_D, M_D, M_D, M_B}; + +int main(int argc, char **argv) +{ + void *addr; + int i, node, err, policy, ret = 0; + unsigned long base_start, base_size, new_start, new_size; + struct bitmask *nmask = numa_allocate_nodemask(); + + pagesize = getpagesize(); + node = 1; + + numa_bitmask_setbit(nmask, node); + + addr = mmap(NULL, pagesize * PAGES, PROT_WRITE, + MAP_ANON | MAP_PRIVATE, 0, 0); + if (addr == MAP_FAILED) { + perror("mmap faile: "); + ret = -1; + goto out; + } + + /* make page populate */ + memset(addr, 0, pagesize * PAGES); + + /* base1 mbind */ + base_start = (unsigned long)addr + pagesize * base1.offset; + base_size = pagesize * base1.size; + err = mbind((void *)base_start, base_size, base1.policy, nmask->maskp, + nmask->size, MPOL_MF_MOVE_ALL); + if (err != 0) { + perror("base1 mbind fail: "); + ret = -1; + goto out; + } + printf("base1 mbind: 0x%lx - 0x%lx policy:%d\n", + base_start, base_start + base_size, base1.policy); + + /* base2 mbind */ + base_start = (unsigned long)addr + pagesize * base2.offset; + base_size = pagesize * base2.size; + err = mbind((void *)base_start, base_size, base2.policy, nmask->maskp, + nmask->size, MPOL_MF_MOVE_ALL); + if (err != 0) { + perror("base2 mbind fail: "); + ret = -1; + goto out; + } + printf("base2 mbind: 0x%lx - 0x%lx policy:%d\n", + base_start, base_start + base_size, base2.policy); + + /* new mbind */ + new_start = (unsigned long)addr + pagesize * new.offset; + new_size = pagesize * new.size; + err = mbind((void *)new_start, new_size, new.policy, + NULL, 0, 0); + if (err != 0) { + perror("new mbind fail: "); + ret = -1; + goto out; + } + printf("new mbind: 0x%lx - 0x%lx policy:%d\n", + new_start, new_start + new_size, new.policy); + + for (i = 0; i < PAGES; i++) { + err = get_mempolicy(&policy, nmask->maskp, nmask->size, + addr + pagesize * i, MPOL_F_ADDR); + if (err != 0) { + perror("get_mempolicy fail: "); + ret = -1; + goto out; + } + + if (policy != expect_policies[i]) { + printf("[NG] policy[%d] is %d (expected %d)\n", + i, policy, expect_policies[i]); + ret = -1; + goto out; + } + } + + printf("[OK] policies are expected\n"); +out: + return ret; +} diff --git a/test/issues/1384/Makefile b/test/issues/1384/Makefile new file mode 100644 index 00000000..9f3dcde7 --- /dev/null +++ b/test/issues/1384/Makefile @@ -0,0 +1,11 @@ +CFLAGS=-g +LDFLAGS=-lnuma + +TARGET=C1384T01 C1384T02 C1384T03 C1384T04 C1384T05 C1384T06 + +all: $(TARGET) + +test: all + ./C1384.sh +clean: + rm -f $(TARGET) *.o *.txt diff --git a/test/issues/1384/README b/test/issues/1384/README new file mode 100644 index 00000000..ff3c2bfd --- /dev/null +++ b/test/issues/1384/README @@ -0,0 +1,30 @@ +【Issue#1384 動作確認】 +□ テスト内容 +本Issueの症状は、既に設定されたvm_policyのメモリ範囲(以下、既存範囲と呼ぶ)と、 +新たに設定するvm_policyのメモリ範囲(以下、新規範囲)が重複している形で +mbind()を実行することで発生する。 + +1. 既存範囲と新規範囲のそれぞれの重複パターンでmbindを実行し、症状が発生しないことを確認する +C1384T01: 既存範囲の前部分と、新規範囲の後部分が重複 +C1384T02: 既存範囲と新規範囲が一致 +C1384T03: 既存範囲が新規範囲を包含している +C1384T04: 既存範囲の後部分と、新規範囲の前部分が重複 +C1384T05: 新規範囲が複数の既存範囲を包含している +C1384T06: 新規範囲が複数の既存範囲に重複している + +3. 以下のLTPを用いて既存のmbind機能に影響が無いことを確認 + - vma02 + - mbind01 + - get_mempolicy01 + +□ 実行手順 +$ make test + +McKernelのインストール先や、OSTEST, LTPの配置場所は、 +$HOME/.mck_test_config を参照している +.mck_test_config は、McKernelをビルドした際に生成されるmck_test_config.sample ファイルを +$HOMEにコピーし、適宜編集する + +□ 実行結果 +x86_64_result.log aarch64_result.log 参照。 +すべての項目をPASSしていることを確認。 diff --git a/test/issues/1384/aarch64_result.log b/test/issues/1384/aarch64_result.log new file mode 100644 index 00000000..d3f97369 --- /dev/null +++ b/test/issues/1384/aarch64_result.log @@ -0,0 +1,127 @@ +*** C1384T01 start ******************************* +base mbind: 0x100000290000 - 0x1000002c0000 policy:2 +new mbind: 0x100000280000 - 0x1000002b0000 policy:0 +[OK] policies are expected +*** C1384T01 PASSED ****************************** + +*** C1384T02 start ******************************* +base mbind: 0x100000290000 - 0x1000002c0000 policy:2 +new mbind: 0x100000290000 - 0x1000002c0000 policy:0 +[OK] policies are expected +*** C1384T02 PASSED ****************************** + +*** C1384T03 start ******************************* +base mbind: 0x100000280000 - 0x1000002d0000 policy:2 +new mbind: 0x100000290000 - 0x1000002c0000 policy:0 +[OK] policies are expected +*** C1384T03 PASSED ****************************** + +*** C1384T04 start ******************************* +base mbind: 0x100000290000 - 0x1000002c0000 policy:2 +new mbind: 0x1000002a0000 - 0x1000002d0000 policy:0 +[OK] policies are expected +*** C1384T04 PASSED ****************************** + +*** C1384T05 start ******************************* +base1 mbind: 0x100000290000 - 0x1000002a0000 policy:2 +base2 mbind: 0x100000290000 - 0x1000002c0000 policy:2 +new mbind: 0x100000280000 - 0x1000002d0000 policy:0 +[OK] policies are expected +*** C1384T05 PASSED ****************************** + +*** C1384T06 start ******************************* +base1 mbind: 0x100000280000 - 0x1000002b0000 policy:2 +base2 mbind: 0x1000002b0000 - 0x1000002d0000 policy:2 +new mbind: 0x100000290000 - 0x1000002c0000 policy:0 +[OK] policies are expected +*** C1384T06 PASSED ****************************** + +*** C1384T07 start ******************************* +vma02 0 TINFO : pid = 46749 addr = 0x1000002c0000 +vma02 0 TINFO : start = 0x1000002c0000, end = 0x1000002f0000 +vma02 1 TPASS : only 1 VMA. +*** C1384T07 PASSED (1) + +*** C1384T08 start ******************************* +tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s +mbind01.c:181: INFO: case MPOL_DEFAULT +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_DEFAULT (target exists) +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_BIND (no target) +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_BIND +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_INTERLEAVE (no target) +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_INTERLEAVE +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_PREFERRED (no target) +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_PREFERRED +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case UNKNOWN_POLICY +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_DEFAULT (invalid flags) +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_PREFERRED (invalid nodemask) +mbind01.c:230: PASS: Test passed + +Summary: +passed 11 +failed 0 +skipped 0 +warnings 0 +*** C1384T08 PASSED (11) + +*** C1384T09 start ******************************* +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=-1 errno=14 (Bad address) +RESULT: return value(ret)=-1 errno=14 (Bad address) +EXPECT: return value(ret)=-1 errno=22 (Invalid argument) +RESULT: return value(ret)=-1 errno=22 (Invalid argument) +get_mempolicy01 0 TINFO : (case00) START +get_mempolicy01 1 TPASS : (case00) END +get_mempolicy01 0 TINFO : (case01) START +get_mempolicy01 2 TPASS : (case01) END +get_mempolicy01 0 TINFO : (case02) START +get_mempolicy01 3 TPASS : (case02) END +get_mempolicy01 0 TINFO : (case03) START +get_mempolicy01 4 TPASS : (case03) END +get_mempolicy01 0 TINFO : (case04) START +get_mempolicy01 5 TPASS : (case04) END +get_mempolicy01 0 TINFO : (case05) START +get_mempolicy01 6 TPASS : (case05) END +get_mempolicy01 0 TINFO : (case06) START +get_mempolicy01 7 TPASS : (case06) END +get_mempolicy01 0 TINFO : (case07) START +get_mempolicy01 8 TPASS : (case07) END +get_mempolicy01 0 TINFO : (case08) START +get_mempolicy01 9 TPASS : (case08) END +get_mempolicy01 0 TINFO : (case09) START +get_mempolicy01 10 TPASS : (case09) END +get_mempolicy01 0 TINFO : (case10) START +get_mempolicy01 11 TPASS : (case10) END +get_mempolicy01 0 TINFO : (case11) START +get_mempolicy01 12 TPASS : (case11) END +*** C1384T09 PASSED (12) + diff --git a/test/issues/1384/x86_64_result.log b/test/issues/1384/x86_64_result.log new file mode 100644 index 00000000..b72a4536 --- /dev/null +++ b/test/issues/1384/x86_64_result.log @@ -0,0 +1,127 @@ +*** C1384T01 start ******************************* +base mbind: 0x2aaaab211000 - 0x2aaaab214000 policy:2 +new mbind: 0x2aaaab210000 - 0x2aaaab213000 policy:0 +[OK] policies are expected +*** C1384T01 PASSED ****************************** + +*** C1384T02 start ******************************* +base mbind: 0x2aaaab211000 - 0x2aaaab214000 policy:2 +new mbind: 0x2aaaab211000 - 0x2aaaab214000 policy:0 +[OK] policies are expected +*** C1384T02 PASSED ****************************** + +*** C1384T03 start ******************************* +base mbind: 0x2aaaab210000 - 0x2aaaab215000 policy:2 +new mbind: 0x2aaaab211000 - 0x2aaaab214000 policy:0 +[OK] policies are expected +*** C1384T03 PASSED ****************************** + +*** C1384T04 start ******************************* +base mbind: 0x2aaaab211000 - 0x2aaaab214000 policy:2 +new mbind: 0x2aaaab212000 - 0x2aaaab215000 policy:0 +[OK] policies are expected +*** C1384T04 PASSED ****************************** + +*** C1384T05 start ******************************* +base1 mbind: 0x2aaaab211000 - 0x2aaaab212000 policy:2 +base2 mbind: 0x2aaaab211000 - 0x2aaaab214000 policy:2 +new mbind: 0x2aaaab210000 - 0x2aaaab215000 policy:0 +[OK] policies are expected +*** C1384T05 PASSED ****************************** + +*** C1384T06 start ******************************* +base1 mbind: 0x2aaaab210000 - 0x2aaaab213000 policy:2 +base2 mbind: 0x2aaaab213000 - 0x2aaaab215000 policy:2 +new mbind: 0x2aaaab211000 - 0x2aaaab214000 policy:0 +[OK] policies are expected +*** C1384T06 PASSED ****************************** + +*** C1384T07 start ******************************* +vma02 0 TINFO : pid = 5920 addr = 0x2aaaab42c000 +vma02 0 TINFO : start = 0x2aaaab42c000, end = 0x2aaaab42f000 +vma02 1 TPASS : only 1 VMA. +*** C1384T07 PASSED (1) + +*** C1384T08 start ******************************* +tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s +mbind01.c:181: INFO: case MPOL_DEFAULT +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_DEFAULT (target exists) +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_BIND (no target) +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_BIND +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_INTERLEAVE (no target) +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_INTERLEAVE +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_PREFERRED (no target) +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_PREFERRED +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case UNKNOWN_POLICY +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_DEFAULT (invalid flags) +mbind01.c:230: PASS: Test passed +mbind01.c:181: INFO: case MPOL_PREFERRED (invalid nodemask) +mbind01.c:230: PASS: Test passed + +Summary: +passed 11 +failed 0 +skipped 0 +warnings 0 +*** C1384T08 PASSED (11) + +*** C1384T09 start ******************************* +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=0 errno=0 (Success) +RESULT: return value(ret)=0 errno=0 (Success) +EXPECT: return value(ret)=-1 errno=14 (Bad address) +RESULT: return value(ret)=-1 errno=14 (Bad address) +EXPECT: return value(ret)=-1 errno=22 (Invalid argument) +RESULT: return value(ret)=-1 errno=22 (Invalid argument) +get_mempolicy01 0 TINFO : (case00) START +get_mempolicy01 1 TPASS : (case00) END +get_mempolicy01 0 TINFO : (case01) START +get_mempolicy01 2 TPASS : (case01) END +get_mempolicy01 0 TINFO : (case02) START +get_mempolicy01 3 TPASS : (case02) END +get_mempolicy01 0 TINFO : (case03) START +get_mempolicy01 4 TPASS : (case03) END +get_mempolicy01 0 TINFO : (case04) START +get_mempolicy01 5 TPASS : (case04) END +get_mempolicy01 0 TINFO : (case05) START +get_mempolicy01 6 TPASS : (case05) END +get_mempolicy01 0 TINFO : (case06) START +get_mempolicy01 7 TPASS : (case06) END +get_mempolicy01 0 TINFO : (case07) START +get_mempolicy01 8 TPASS : (case07) END +get_mempolicy01 0 TINFO : (case08) START +get_mempolicy01 9 TPASS : (case08) END +get_mempolicy01 0 TINFO : (case09) START +get_mempolicy01 10 TPASS : (case09) END +get_mempolicy01 0 TINFO : (case10) START +get_mempolicy01 11 TPASS : (case10) END +get_mempolicy01 0 TINFO : (case11) START +get_mempolicy01 12 TPASS : (case11) END +*** C1384T09 PASSED (12) +