diff --git a/kernel/include/process.h b/kernel/include/process.h index 0faf40a0..000da5b9 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -406,6 +406,7 @@ struct vm_range_numa_policy { unsigned long start, end; DECLARE_BITMAP(numa_mask, PROCESS_NUMA_MASK_BITS); int numa_mem_policy; + int il_prev; }; struct vm_regions { @@ -797,6 +798,7 @@ struct process_vm { long currss; DECLARE_BITMAP(numa_mask, PROCESS_NUMA_MASK_BITS); int numa_mem_policy; + int il_prev; /* Protected by memory_range_lock */ struct rb_root vm_range_numa_policy_tree; struct vm_range *range_cache[VM_RANGE_CACHE_SIZE]; diff --git a/kernel/mem.c b/kernel/mem.c index f603b2c0..62562cf4 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -523,6 +523,18 @@ static void reserve_pages(struct ihk_page_allocator_desc *pa_allocator, ihk_pagealloc_reserve(pa_allocator, start, end); } +static int interleave_nodes(int off, unsigned long *numa_mask) +{ + int next; + + next = find_next_bit(numa_mask, PROCESS_NUMA_MASK_BITS, off + 1); + if (next >= PROCESS_NUMA_MASK_BITS) { + next = find_first_bit(numa_mask, PROCESS_NUMA_MASK_BITS); + } + + return next; +} + extern int cpu_local_var_initialized; static void *mckernel_allocate_aligned_pages_node(int npages, int p2align, ihk_mc_ap_flag flag, int pref_node, int is_user, uintptr_t virt_addr) @@ -538,7 +550,9 @@ static void *mckernel_allocate_aligned_pages_node(int npages, int p2align, int numa_mem_policy = -1; struct process_vm *vm; struct vm_range *range = NULL; - int chk_shm = 0; + int chk_shm = 0, il_start, looping; + int *il_prev = NULL; + unsigned long *numa_mask = NULL; if(npages <= 0) return NULL; @@ -549,31 +563,39 @@ static void *mckernel_allocate_aligned_pages_node(int npages, int p2align, !cpu_local_var(current)->vm) goto distance_based; - /* No explicitly requested NUMA or user policy? */ - if ((pref_node == -1) && (!(flag & IHK_MC_AP_USER) || - cpu_local_var(current)->vm->numa_mem_policy == MPOL_DEFAULT)) { + vm = cpu_local_var(current)->vm; + node = ihk_mc_get_numa_id(); - if (virt_addr != -1) { - vm = cpu_local_var(current)->vm; - range_policy_iter = vm_range_policy_search(vm, virt_addr); - if (range_policy_iter) { - range = lookup_process_memory_range(vm, (uintptr_t)virt_addr, ((uintptr_t)virt_addr) + 1); - if (range) { - if( (range->memobj) && (range->memobj->flags == MF_SHM)) { - chk_shm = 1; - } - } + /* Get mempolicy user requested */ + if (virt_addr != -1) { + range_policy_iter = vm_range_policy_search(vm, virt_addr); + + if (range_policy_iter) { + range = lookup_process_memory_range(vm, + (uintptr_t)virt_addr, + ((uintptr_t)virt_addr) + 1); + if ((range && (range->memobj->flags == MF_SHM))) { + chk_shm = 1; } + + /* Use range policy */ + numa_mem_policy = range_policy_iter->numa_mem_policy; + numa_mask = range_policy_iter->numa_mask; + il_prev = &range_policy_iter->il_prev; + } else { + /* Use process policy */ + numa_mem_policy = vm->numa_mem_policy; + numa_mask = vm->numa_mask; + il_prev = &vm->il_prev; } - - - if ((!((range_policy_iter) && (range_policy_iter->numa_mem_policy != MPOL_DEFAULT))) && (chk_shm == 0)) - goto distance_based; } - node = ihk_mc_get_numa_id(); - if (!memory_nodes[node].nodes_by_distance) - goto order_based; + /* No explicitly requested NUMA or user policy? */ + if ((pref_node == -1) && !(flag & IHK_MC_AP_USER)) { + if ((numa_mem_policy == MPOL_DEFAULT) && (chk_shm == 0)) { + goto distance_based; + } + } /* Explicit valid node? */ if (pref_node > -1 && pref_node < ihk_mc_get_nr_numa_nodes()) { @@ -615,27 +637,6 @@ static void *mckernel_allocate_aligned_pages_node(int npages, int p2align, } } - if ((virt_addr != -1) && (chk_shm == 0)) { - - vm = cpu_local_var(current)->vm; - - if (!(range_policy_iter)) { - range_policy_iter = vm_range_policy_search(vm, virt_addr); - } - - if (range_policy_iter) { - range = lookup_process_memory_range(vm, (uintptr_t)virt_addr, ((uintptr_t)virt_addr) + 1); - if ((range && (range->memobj->flags == MF_SHM))) { - chk_shm = 1; - } else { - numa_mem_policy = range_policy_iter->numa_mem_policy; - } - } - } - - if (numa_mem_policy == -1) - numa_mem_policy = cpu_local_var(current)->vm->numa_mem_policy; - switch (numa_mem_policy) { case MPOL_BIND: case MPOL_PREFERRED: @@ -687,7 +688,55 @@ static void *mckernel_allocate_aligned_pages_node(int npages, int p2align, break; case MPOL_INTERLEAVE: - /* TODO: */ + /* Initialize interleave */ + il_start = *il_prev; + looping = 0; + +retry_interleave: + /* Find next node */ + numa_id = interleave_nodes(*il_prev, numa_mask); + *il_prev = numa_id; + + if (il_start == *il_prev && looping) { + /* All interleave nodes are full */ + pa = 0; + break; + } + looping = 1; +#ifdef IHK_RBTREE_ALLOCATOR + { + if (rusage_check_oom(numa_id, npages, is_user) + == -ENOMEM) { + goto retry_interleave; + } else { + pa = ihk_numa_alloc_pages( + &memory_nodes[numa_id], + npages, p2align); + } +#else + list_for_each_entry(pa_allocator, + &memory_nodes[numa_id].allocators, + list) { + if (rusage_check_oom(numa_id, npages, is_user) + == -ENOMEM) { + goto retry_interleave; + } else { + pa = ihk_pagealloc_alloc(pa_allocator, + npages, p2align); + } +#endif + + if (pa) { + rusage_page_add(numa_id, npages, + is_user); + dkprintf("%s: policy: CPU @ node %d allocated " + "%d pages from node %d\n", + __func__, + ihk_mc_get_numa_id(), + npages, node); + + } + } break; default: diff --git a/kernel/syscall.c b/kernel/syscall.c index 0a540731..817bfb00 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -9923,6 +9923,10 @@ mbind_update_only: sizeof(numa_mask)); } range_policy->numa_mem_policy = mode; + if (mode == MPOL_INTERLEAVE) { + range_policy->il_prev = + PROCESS_NUMA_MASK_BITS - 1; + } break; @@ -10084,6 +10088,9 @@ SYSCALL_DECLARE(set_mempolicy) } vm->numa_mem_policy = mode; + if (mode == MPOL_INTERLEAVE) { + vm->il_prev = PROCESS_NUMA_MASK_BITS - 1; + } error = 0; break; diff --git a/test/issues/959/C959.sh b/test/issues/959/C959.sh new file mode 100755 index 00000000..d779d627 --- /dev/null +++ b/test/issues/959/C959.sh @@ -0,0 +1,125 @@ +#/bin/sh + +USELTP=1 +USEOSTEST=1 + +LTP_LIST="mbind01 get_mempolicy01" +OSTEST_MBIND_LIST="1 3 5 9 12 14 15 16 20 24 26 28 30" + +BOOTPARAM="-c 1-7 -m 10G@0,10G@1 -O -e anon_on_demand" +. ../../common.sh + +issue="959" +tid=01 +arch=`uname -p` + +tname=`printf "C${issue}T%02d" ${tid}` +echo "*** ${tname} start *******************************" +sudo ${MCEXEC} ./check_mempol_il 1 30 6 3 3 3 + +if [ $? -eq 0 ]; then + echo "*** ${tname} PASSED ******************************" +else + echo "*** ${tname} FAILED ******************************" +fi +let tid++ +echo "" + +tname=`printf "C${issue}T%02d" ${tid}` +echo "*** ${tname} start *******************************" +sudo ${MCEXEC} ./check_mempol_il 2 30 6 3 3 3 + +if [ $? -eq 0 ]; then + echo "*** ${tname} PASSED ******************************" +else + echo "*** ${tname} FAILED ******************************" +fi +let tid++ +echo "" + +tname=`printf "C${issue}T%02d" ${tid}` +echo "*** ${tname} start *******************************" +sudo ${MCEXEC} ./check_mempol_il 1 30 6 2 0 6 + +if [ $? -eq 0 ]; then + echo "*** ${tname} PASSED ******************************" +else + echo "*** ${tname} FAILED ******************************" +fi +let tid++ +echo "" + +tname=`printf "C${issue}T%02d" ${tid}` +echo "*** ${tname} start *******************************" +sudo ${MCEXEC} ./check_mempol_il 2 30 6 2 0 6 + +if [ $? -eq 0 ]; then + echo "*** ${tname} PASSED ******************************" +else + echo "*** ${tname} FAILED ******************************" +fi +let tid++ +echo "" + +BOOTPARAM="-c 1-7 -m 10G@0,2G@1 -O -e anon_on_demand" +mcstop +mcreboot + +tname=`printf "C${issue}T%02d" ${tid}` +echo "*** ${tname} start *******************************" +${IHKOSCTL} 0 clear_kmsg +sudo ${MCEXEC} ./check_mempol_il 1 30 6 2 4 2 +ret=$? +dbg_prints=`${IHKOSCTL} 0 kmsg | grep "TEST_959" | wc -l` + +if [ ${ret} -eq 0 -a ${dbg_prints} -gt 0 ]; then + echo "*** ${tname} PASSED ******************************" +else + echo "*** ${tname} FAILED ******************************" +fi +let tid++ +echo "" + +tname=`printf "C${issue}T%02d" ${tid}` +echo "*** ${tname} start *******************************" +sudo ${MCEXEC} ./check_mempol_il 2 30 6 2 4 2 +ret=$? +dbg_prints=`${IHKOSCTL} 0 kmsg | grep "TEST_959" | wc -l` + +if [ ${ret} -eq 0 -a ${dbg_prints} -gt 0 ]; then + echo "*** ${tname} PASSED ******************************" +else + echo "*** ${tname} FAILED ******************************" +fi +let tid++ +echo "" + +for tp in ${LTP_LIST} +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 + +for tno in ${OSTEST_MBIND_LIST} +do + tname=`printf "C${issue}T%02d" ${tid}` + echo "*** ${tname} start *******************************" + ${MCEXEC} ${TESTMCK} -s mbind -n ${tno} -- -n 2 2>&1 | tee test_mck-mbind${tno}.txt + if [ $? = 0 ]; then + echo "*** ${tname} PASSED" + else + echo "*** ${tname} FAILED" + fi + let tid++ + echo "" +done diff --git a/test/issues/959/Makefile b/test/issues/959/Makefile new file mode 100644 index 00000000..81425256 --- /dev/null +++ b/test/issues/959/Makefile @@ -0,0 +1,14 @@ +include $(HOME)/.mck_test_config.mk + +CFLAGS=-g -O0 -Wall -I$(MCK_DIR)/include +LDFLAGS=-L$(MCK_DIR)/lib64 -lihk -lnuma -Wl,-rpath=$(MCK_DIR)/lib64 + +TARGET=check_mempol_il + +all: $(TARGET) + +test: all + ./C959.sh +clean: + rm -f $(TARGET) *.o *.txt + diff --git a/test/issues/959/README b/test/issues/959/README new file mode 100644 index 00000000..e2f444de --- /dev/null +++ b/test/issues/959/README @@ -0,0 +1,87 @@ +【Issue#959 動作確認】 +□ テスト内容 +本テストは2つのNUMAノード(node0, node1)を使用してMPOL_INTERLEAVEの動作を確認するテストである。 +2つ以上のNUMAノードを持つ環境で実行すること。 + +1. INTERLEAVEするノードセットに十分なメモリ容量がある場合の動作確認 +C959T01: set_mempolicyによるmempolicy設定時の動作 (2ノード) + node0, node1 からそれぞれ10GBのメモリをMcKernelに割り当てた状態で + 下記の処理を確認する + (1) set_mempolicy() でプロセスのmempolicyを、node0, node1 でのINTERLEAVEに設定する + (2) 6GBのメモリを確保し、書き込みを行う + (3) McKernelの2つのNUMAノードから均等にメモリが使用されていることを確認する + +C959T02: mbindによるmempolicy設定時の動作 (2ノード) + node0, node1 からそれぞれ10GBのメモリをMcKernelに割り当てた状態で + 下記の処理を確認する + (1) set_mempolicy() でプロセスのmempolicyを、node0 でのBINDに設定する + (2) 6GBのメモリを確保する + (3) mbind() で(2)で確保した領域のmempolicyを、node0, node1 でのINTERLEAVEに設定する + (4) McKernelの2つのNUMAノードから均等にメモリが使用されていることを確認する + +C959T03: set_mempolicyによるmempolicy設定時の動作 (1ノード) + node0, node1 からそれぞれ10GBのメモリをMcKernelに割り当てた状態で + 下記の処理を確認する + (1) set_mempolicy() でプロセスのmempolicyを、 node1 でのINTERLEAVEに設定する + (2) 6GBのメモリを確保し、書き込みを行う + (3) McKernelのnode1から 6GBが使用されていることを確認する + +C959T04: mbindによるmempolicy設定時の動作 (2ノード) + node0, node1 からそれぞれ10GBのメモリをMcKernelに割り当てた状態で + 下記の処理を確認する + (1) set_mempolicy() でプロセスのmempolicyを、node0 でのBINDに設定する + (2) 6GBのメモリを確保する + (3) mbind() で(2)で確保した領域のmempolicyを、node1 でのINTERLEAVEに設定する + (4) McKernelのnode1から 6GBが使用されていることを確認する + +2. INTERLEAVEするノードセットにメモリ容量が不足している場合の動作確認 +C959T05: set_mempolicyによるmempolicy設定時の動作 + node0 に10GB、 node1 に2GBのメモリをそれぞれMcKernelに割り当てた状態で + 下記の処理を確認する + (1) set_mempolicy() でプロセスのmempolicyを、node1 でのINTERLEAVEに設定する + (2) 6GBのメモリを確保し、書き込みを行う + (3) McKernelのnode0から4GB, node1から2GBがそれぞれ使用されていることを確認する + +C959T06: mbindによるmempolicy設定時の動作 + node0 に10GB、 node1 に2GBのメモリをそれぞれMcKernelに割り当てた状態で + 下記の処理を確認する + (1) set_mempolicy() でプロセスのmempolicyを、node0 でのBINDに設定する + (2) 6GBのメモリを確保する + (3) mbind() で(2)で確保した領域のmempolicyを、node1 でのINTERLEAVEに設定する + (4) McKernelのnode0から4GB, node1から2GBがそれぞれ使用されていることを確認する + +3. 以下のLTPを用いて既存のmbind機能に影響がないことを確認する + - mbind01 + - get_mempolicy01 + +4. 以下のOSTESTを用いて既存のmbind機能に影響がないことを確認する + - ostest-mbind.000 + - ostest-mbind.001 + - ostest-mbind.002 + - ostest-mbind.003 + - ostest-mbind.004 + - ostest-mbind.005 + - ostest-mbind.006 + - ostest-mbind.007 + - ostest-mbind.008 + - ostest-mbind.009 + - ostest-mbind.010 + - ostest-mbind.011 + - ostest-mbind.012 + +□ 実行手順 +・下記の手順でテストを実行する +$ cd +$ patch -p0 < test/issues/959/test_print.patch +(build mckernel) +$ cd test/issues/959 +$ make test + +McKernelのインストール先や、OSTEST, LTPの配置場所は、 +$HOME/.mck_test_config を参照している +.mck_test_config は、McKernelをビルドした際に生成されるmck_test_config.sample ファイルを +$HOMEにコピーし、適宜編集する + +□ 実行結果 +x86_64result.log, aarch64_result.log 参照。 +すべての項目をPASSしていることを確認。 diff --git a/test/issues/959/aarch64_result.log b/test/issues/959/aarch64_result.log new file mode 100644 index 00000000..651da780 --- /dev/null +++ b/test/issues/959/aarch64_result.log @@ -0,0 +1,314 @@ +mcstop+release.sh ... done +mcreboot.sh -c 1-7 -m 10G@0,10G@1 -O -e anon_on_demand ... done +*** C959T01 start ******************************* +INTERLEAVE BIT_MASK: 0x3 +set_mempolicy: INTERLEAVE mask 0x3 +** Difference of numa_stat ** +[OK] NUMA[0] 0xc0000000 +[OK] NUMA[1] 0xc0000000 +*** C959T01 PASSED ****************************** + +*** C959T02 start ******************************* +INTERLEAVE BIT_MASK: 0x3 +set_mempolicy: BIND mask 0x1 +mbind : INTERLEAVE mask 0x3 +** Difference of numa_stat ** +[OK] NUMA[0] 0xc0000000 +[OK] NUMA[1] 0xc0000000 +*** C959T02 PASSED ****************************** + +*** C959T03 start ******************************* +INTERLEAVE BIT_MASK: 0x2 +set_mempolicy: INTERLEAVE mask 0x2 +** Difference of numa_stat ** +[OK] NUMA[0] 0x0 +[OK] NUMA[1] 0x180000000 +*** C959T03 PASSED ****************************** + +*** C959T04 start ******************************* +INTERLEAVE BIT_MASK: 0x2 +set_mempolicy: BIND mask 0x1 +mbind : INTERLEAVE mask 0x2 +** Difference of numa_stat ** +[OK] NUMA[0] 0x0 +[OK] NUMA[1] 0x180000000 +*** C959T04 PASSED ****************************** + +mcstop+release.sh ... done +mcreboot.sh -c 1-7 -m 10G@0,2G@1 -O -e anon_on_demand ... done +*** C959T05 start ******************************* +INTERLEAVE BIT_MASK: 0x2 +set_mempolicy: INTERLEAVE mask 0x2 +** Difference of numa_stat ** +[OK] NUMA[0] 0x100000000 +[OK] NUMA[1] 0x80000000 +*** C959T05 PASSED ****************************** + +*** C959T06 start ******************************* +INTERLEAVE BIT_MASK: 0x2 +set_mempolicy: BIND mask 0x1 +mbind : INTERLEAVE mask 0x2 +** Difference of numa_stat ** +[OK] NUMA[0] 0x100000000 +[OK] NUMA[1] 0x80000000 +*** C959T06 PASSED ****************************** + +*** C959T07 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 +*** C959T07 PASSED (11) + +*** C959T08 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 +*** C959T08 PASSED (12) + +*** C959T09 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 1 +ARGS: -n 2 +RESULT: ok +*** C959T09 PASSED + +*** C959T10 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 3 +ARGS: -n 2 +RESULT: ok +*** C959T10 PASSED + +*** C959T11 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 5 +ARGS: -n 2 +RESULT: ok +*** C959T11 PASSED + +*** C959T12 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 9 +ARGS: -n 2 +RESULT: ok +*** C959T12 PASSED + +*** C959T13 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 12 +ARGS: -n 2 +RESULT: ok +*** C959T13 PASSED + +*** C959T14 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 14 +ARGS: -n 2 +RESULT: ok +*** C959T14 PASSED + +*** C959T15 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 15 +ARGS: -n 2 +region 0 +get : mode = 2, node_mask = 1 +m_expect : mode = 2, node_mask = 1 + +region 1 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +region 2 +get : mode = 3, node_mask = 3 +m_expect : mode = 3, node_mask = 3 + +region 3 +get : mode = 3, node_mask = 3 +m_expect : mode = 3, node_mask = 3 + +region 4 +get : mode = 3, node_mask = 3 +m_expect : mode = 3, node_mask = 3 + +region 5 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +region 6 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +RESULT: ok +*** C959T15 PASSED + +*** C959T16 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 16 +ARGS: -n 2 +region 0 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +region 1 +get : mode = 2, node_mask = 1 +m_expect : mode = 2, node_mask = 1 + +region 2 +get : mode = 2, node_mask = 1 +m_expect : mode = 2, node_mask = 1 + +region 3 +get : mode = 2, node_mask = 1 +m_expect : mode = 2, node_mask = 1 + +region 4 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +region 5 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +region 6 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +RESULT: ok +*** C959T16 PASSED + +*** C959T17 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 20 +ARGS: -n 2 +region 0 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +region 1 +get : mode = 3, node_mask = 3 +m_expect : mode = 3, node_mask = 3 + +region 2 +get : mode = 3, node_mask = 3 +m_expect : mode = 3, node_mask = 3 + +region 3 +get : mode = 2, node_mask = 1 +m_expect : mode = 2, node_mask = 1 + +region 4 +get : mode = 2, node_mask = 1 +m_expect : mode = 2, node_mask = 1 + +region 5 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +region 6 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +RESULT: ok +*** C959T17 PASSED + +*** C959T18 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 24 +ARGS: -n 2 +RESULT: ok +*** C959T18 PASSED + +*** C959T19 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 26 +ARGS: -n 2 +nodemask = 0 +RESULT: ok +*** C959T19 PASSED + +*** C959T20 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 28 +ARGS: -n 2 +RESULT: ok +*** C959T20 PASSED + +*** C959T21 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 30 +ARGS: -n 2 +RESULT: ok +*** C959T21 PASSED + diff --git a/test/issues/959/check_mempol_il.c b/test/issues/959/check_mempol_il.c new file mode 100644 index 00000000..76192b94 --- /dev/null +++ b/test/issues/959/check_mempol_il.c @@ -0,0 +1,139 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUMA_NUM 2 + +long long numa_stat_bfr[NUMA_NUM], numa_stat_aft[NUMA_NUM]; +long long exp_diff[NUMA_NUM]; + +int +get_current_numa_stat(long long *stat, int numa_cnt) +{ + int i, ret = 0; + struct ihk_os_rusage mck_rusage; + + memset(&mck_rusage, 0, sizeof(mck_rusage)); + ret = ihk_os_getrusage(0, &mck_rusage, sizeof(mck_rusage)); + if (ret) { + perror("ihk_os_getrusage()"); + goto out; + } + + for (i = 0; i < numa_cnt; i++) { + if (mck_rusage.memory_numa_stat[i] != 0) { + stat[i] = mck_rusage.memory_numa_stat[i]; + } + } +out: + return ret; +} + +int +main(int argc, char **argv) +{ + void *p; + unsigned long mask, bind_mask = 1; + unsigned long ps; + int i, mode, pgshift, pgnum, exp_0, exp_1, ret = 0; + + if (argc < 7) { + printf("error: too few arguments\n"); + ret = -1; + goto out; + } + + mode = atoi(argv[1]); /* 1: set_mempolicy, 2: mbind */ + pgshift = atoi(argv[2]); + pgnum = atoi(argv[3]); + mask = atoi(argv[4]); + exp_0 = atoi(argv[5]); + exp_1 = atoi(argv[6]); + + ps = 1UL << pgshift; + exp_diff[0] = exp_0 * ps; + exp_diff[1] = exp_1 * ps; + + if (mode != 1 && mode != 2) { + printf("error: invalid mode\n"); + ret = -1; + goto out; + } + + printf("INTERLEAVE BIT_MASK: 0x%lx\n", mask); + + get_current_numa_stat(numa_stat_bfr, NUMA_NUM); + switch (mode) { + case 1: /* set_mempolicy */ + printf("set_mempolicy: INTERLEAVE mask 0x%lx\n", mask); + if (set_mempolicy(MPOL_INTERLEAVE, &mask, NUMA_NUM)) { + perror("set_mempolicy"); + ret = -1; + goto out; + } + + p = mmap(NULL, ps * pgnum, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if (p == ((void *)-1)) { + perror("mmap"); + ret = -1; + goto out; + } + break; + case 2: /* mbind */ + printf("set_mempolicy: BIND mask 0x%lx\n", bind_mask); + if (set_mempolicy(MPOL_BIND, &bind_mask, NUMA_NUM)) { + perror("set_mempolicy"); + ret = -1; + goto out; + } + + p = mmap(NULL, ps * pgnum, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if (p == ((void *)-1)) { + perror("mmap"); + ret = -1; + goto out; + } + + printf("mbind : INTERLEAVE mask 0x%lx\n", mask); + if (mbind(p, ps * pgnum, MPOL_INTERLEAVE, &mask, + NUMA_NUM, 0) == -1) { + perror("mbind"); + ret = -1; + goto out; + } + break; + default: + printf("error: invalid mode\n"); + ret = -1; + goto out; + } + + memset(p, '0', ps * pgnum); + + get_current_numa_stat(numa_stat_aft, NUMA_NUM); + + printf("** Difference of numa_stat **\n"); + for (i = 0; i < NUMA_NUM; i++) { + long long diff = numa_stat_aft[i] - numa_stat_bfr[i]; + + if (diff == exp_diff[i]) { + printf("[OK] "); + } else { + printf("[NG] "); + ret = -1; + } + printf(" NUMA[%d] 0x%llx\n", i, diff); + } + + munmap(p, ps * pgnum); +out: + return ret; +} diff --git a/test/issues/959/test_print.patch b/test/issues/959/test_print.patch new file mode 100644 index 00000000..3e2f1372 --- /dev/null +++ b/test/issues/959/test_print.patch @@ -0,0 +1,14 @@ +diff --git kernel/mem.c kernel/mem.c +index e464eb2..7086c6a 100644 +--- kernel/mem.c ++++ kernel/mem.c +@@ -749,6 +749,9 @@ retry_interleave: + #endif + dkprintf("%s: couldn't fulfill user policy for %d pages\n", + __FUNCTION__, npages); ++ if (numa_mem_policy == MPOL_INTERLEAVE) { ++ kprintf("TEST_959: reach HERE\n"); ++ } + } + + distance_based: diff --git a/test/issues/959/x86_64_result.log b/test/issues/959/x86_64_result.log new file mode 100644 index 00000000..7ca4e8fd --- /dev/null +++ b/test/issues/959/x86_64_result.log @@ -0,0 +1,313 @@ +mcstop+release.sh ... done +mcreboot.sh -c 1-7 -m 10G@0,10G@1 -O -e anon_on_demand ... done +*** C959T01 start ******************************* +INTERLEAVE BIT_MASK: 0x3 +set_mempolicy: INTERLEAVE mask 0x3 +** Difference of numa_stat ** +[OK] NUMA[0] 0xc0000000 +[OK] NUMA[1] 0xc0000000 +*** C959T01 PASSED ****************************** + +*** C959T02 start ******************************* +INTERLEAVE BIT_MASK: 0x3 +set_mempolicy: BIND mask 0x1 +mbind : INTERLEAVE mask 0x3 +** Difference of numa_stat ** +[OK] NUMA[0] 0xc0000000 +[OK] NUMA[1] 0xc0000000 +*** C959T02 PASSED ****************************** + +*** C959T03 start ******************************* +INTERLEAVE BIT_MASK: 0x2 +set_mempolicy: INTERLEAVE mask 0x2 +** Difference of numa_stat ** +[OK] NUMA[0] 0x0 +[OK] NUMA[1] 0x180000000 +*** C959T03 PASSED ****************************** + +*** C959T04 start ******************************* +INTERLEAVE BIT_MASK: 0x2 +set_mempolicy: BIND mask 0x1 +mbind : INTERLEAVE mask 0x2 +** Difference of numa_stat ** +[OK] NUMA[0] 0x0 +[OK] NUMA[1] 0x180000000 +*** C959T04 PASSED ****************************** + +mcstop+release.sh ... done +mcreboot.sh -c 1-7 -m 10G@0,2G@1 -O -e anon_on_demand ... done +*** C959T05 start ******************************* +INTERLEAVE BIT_MASK: 0x2 +set_mempolicy: INTERLEAVE mask 0x2 +** Difference of numa_stat ** +[OK] NUMA[0] 0x100000000 +[OK] NUMA[1] 0x80000000 +*** C959T05 PASSED ****************************** + +*** C959T06 start ******************************* +INTERLEAVE BIT_MASK: 0x2 +set_mempolicy: BIND mask 0x1 +mbind : INTERLEAVE mask 0x2 +** Difference of numa_stat ** +[OK] NUMA[0] 0x100000000 +[OK] NUMA[1] 0x80000000 +*** C959T06 PASSED ****************************** + +*** C959T07 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 +*** C959T07 PASSED (11) + +*** C959T08 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 +*** C959T08 PASSED (12) + +*** C959T09 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 1 +ARGS: -n 2 +RESULT: ok +*** C959T09 PASSED + +*** C959T10 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 3 +ARGS: -n 2 +RESULT: ok +*** C959T10 PASSED + +*** C959T11 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 5 +ARGS: -n 2 +RESULT: ok +*** C959T11 PASSED + +*** C959T12 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 9 +ARGS: -n 2 +RESULT: ok +*** C959T12 PASSED + +*** C959T13 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 12 +ARGS: -n 2 +RESULT: ok +*** C959T13 PASSED + +*** C959T14 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 14 +ARGS: -n 2 +RESULT: ok +*** C959T14 PASSED + +*** C959T15 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 15 +ARGS: -n 2 +region 0 +get : mode = 2, node_mask = 1 +m_expect : mode = 2, node_mask = 1 + +region 1 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +region 2 +get : mode = 3, node_mask = 3 +m_expect : mode = 3, node_mask = 3 + +region 3 +get : mode = 3, node_mask = 3 +m_expect : mode = 3, node_mask = 3 + +region 4 +get : mode = 3, node_mask = 3 +m_expect : mode = 3, node_mask = 3 + +region 5 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +region 6 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +RESULT: ok +*** C959T15 PASSED + +*** C959T16 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 16 +ARGS: -n 2 +region 0 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +region 1 +get : mode = 2, node_mask = 1 +m_expect : mode = 2, node_mask = 1 + +region 2 +get : mode = 2, node_mask = 1 +m_expect : mode = 2, node_mask = 1 + +region 3 +get : mode = 2, node_mask = 1 +m_expect : mode = 2, node_mask = 1 + +region 4 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +region 5 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +region 6 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +RESULT: ok +*** C959T16 PASSED + +*** C959T17 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 20 +ARGS: -n 2 +region 0 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +region 1 +get : mode = 3, node_mask = 3 +m_expect : mode = 3, node_mask = 3 + +region 2 +get : mode = 3, node_mask = 3 +m_expect : mode = 3, node_mask = 3 + +region 3 +get : mode = 2, node_mask = 1 +m_expect : mode = 2, node_mask = 1 + +region 4 +get : mode = 2, node_mask = 1 +m_expect : mode = 2, node_mask = 1 + +region 5 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +region 6 +get : mode = 0, node_mask = 0 +m_expect : mode = 0, node_mask = 0 + +RESULT: ok +*** C959T17 PASSED + +*** C959T18 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 24 +ARGS: -n 2 +RESULT: ok +*** C959T18 PASSED + +*** C959T19 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 26 +ARGS: -n 2 +nodemask = 0 +RESULT: ok +*** C959T19 PASSED + +*** C959T20 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 28 +ARGS: -n 2 +RESULT: ok +*** C959T20 PASSED + +*** C959T21 start ******************************* +TEST_SUITE: mbind +TEST_NUMBER: 30 +ARGS: -n 2 +RESULT: ok +*** C959T21 PASSED