mempolicy: Support MPOL_INTERLEAVE

Change-Id: I6357892d792b2de8ea859a0a6799250f05066713
Refs: #959
This commit is contained in:
Ken Sato
2020-07-28 15:14:45 +09:00
committed by Masamichi Takagi
parent 7f0594d784
commit aef50d710c
10 changed files with 1107 additions and 43 deletions

View File

@ -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];

View File

@ -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:

View File

@ -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;

125
test/issues/959/C959.sh Executable file
View File

@ -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

14
test/issues/959/Makefile Normal file
View File

@ -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

87
test/issues/959/README Normal file
View File

@ -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 <mckernel>
$ 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していることを確認。

View File

@ -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

View File

@ -0,0 +1,139 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <numaif.h>
#include <sys/mman.h>
#include <errno.h>
#include <ihklib.h>
#include <ihk/ihk_rusage.h>
#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;
}

View File

@ -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:

View File

@ -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