getrusage: Fix memory_stat_mapped_file when SIGBUS occurs in file map
Change-Id: Ia4686f32a3c888d5c886ab6cc6c2b510885447f5 Refs: #1422
This commit is contained in:
committed by
Masamichi Takagi
parent
baa7a6adcb
commit
9c7d0cfaec
@ -557,10 +557,8 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
struct fileobj *obj = to_fileobj(memobj);
|
||||
int error = -1;
|
||||
void *virt = NULL;
|
||||
int npages;
|
||||
uintptr_t phys = -1;
|
||||
struct page *page;
|
||||
struct pageio_args *args = NULL;
|
||||
struct mcs_lock_node mcs_node;
|
||||
int hash = (off >> PAGE_SHIFT) & FILEOBJ_PAGE_HASH_MASK;
|
||||
|
||||
@ -608,7 +606,6 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
*physp = virt_to_phys(virt);
|
||||
dkprintf("%s: MF_ZEROFILL: off: %lu -> 0x%lx resolved\n",
|
||||
__FUNCTION__, off, virt_to_phys(virt));
|
||||
virt = NULL;
|
||||
goto out_nolock;
|
||||
}
|
||||
|
||||
@ -616,6 +613,7 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
page = __fileobj_page_hash_lookup(obj, hash, off);
|
||||
if (!page || (page->mode == PM_WILL_PAGEIO)
|
||||
|| (page->mode == PM_PAGEIO)) {
|
||||
struct pageio_args *args;
|
||||
args = kmalloc(sizeof(*args), IHK_MC_AP_NOWAIT);
|
||||
if (!args) {
|
||||
error = -ENOMEM;
|
||||
@ -626,7 +624,7 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
}
|
||||
|
||||
if (!page) {
|
||||
npages = 1 << p2align;
|
||||
int npages = 1 << p2align;
|
||||
|
||||
virt = ihk_mc_alloc_pages_user(npages, (IHK_MC_AP_NOWAIT |
|
||||
((to_memobj(obj)->flags & MF_ZEROFILL) ?
|
||||
@ -638,6 +636,7 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
"alloc failed. %d\n",
|
||||
obj, off, p2align, virt_addr, physp,
|
||||
error);
|
||||
kfree(args);
|
||||
goto out;
|
||||
}
|
||||
phys = virt_to_phys(virt);
|
||||
@ -666,8 +665,6 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
proc->pgio_arg = args;
|
||||
|
||||
error = -ERESTART;
|
||||
virt = NULL;
|
||||
args = NULL;
|
||||
goto out;
|
||||
}
|
||||
else if (page->mode == PM_DONE_PAGEIO) {
|
||||
@ -676,11 +673,11 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
}
|
||||
else if (page->mode == PM_PAGEIO_EOF) {
|
||||
error = -ERANGE;
|
||||
goto out;
|
||||
goto pageio_error;
|
||||
}
|
||||
else if (page->mode == PM_PAGEIO_ERROR) {
|
||||
error = -EIO;
|
||||
goto out;
|
||||
goto pageio_error;
|
||||
}
|
||||
|
||||
ihk_atomic_inc(&page->count);
|
||||
@ -688,19 +685,22 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
|
||||
|
||||
error = 0;
|
||||
*physp = page_to_phys(page);
|
||||
virt = NULL;
|
||||
out:
|
||||
mcs_lock_unlock(&obj->page_hash_locks[hash], &mcs_node);
|
||||
out_nolock:
|
||||
if (virt) {
|
||||
ihk_mc_free_pages_user(virt, npages);
|
||||
}
|
||||
if (args) {
|
||||
kfree(args);
|
||||
}
|
||||
dkprintf("fileobj_get_page(%p,%lx,%x,%x,%p): %d %lx\n",
|
||||
obj, off, p2align, virt_addr, physp, error, phys);
|
||||
return error;
|
||||
|
||||
pageio_error:
|
||||
__fileobj_page_hash_remove(page);
|
||||
virt = phys_to_virt(page_to_phys(page));
|
||||
if (page_unmap(page)) {
|
||||
ihk_mc_free_pages_user(virt, 1);
|
||||
kfree(page);
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
static int fileobj_flush_page(struct memobj *memobj, uintptr_t phys,
|
||||
|
||||
74
test/issues/1422/C1422.sh
Executable file
74
test/issues/1422/C1422.sh
Executable file
@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
USELTP=1
|
||||
USEOSTEST=1
|
||||
|
||||
BOOTPARAM="-c 12-15 -m 512M@4"
|
||||
. ../../common.sh
|
||||
|
||||
echo ""
|
||||
echo "*** get_rusage test"
|
||||
echo a > ./tmp
|
||||
BEFORE_STR=`./get_rusage 0 | grep "memory_stat_mapped_file"`
|
||||
$MCEXEC ./filemap_sigbus ./tmp
|
||||
AFTER_STR=`./get_rusage 0 | grep "memory_stat_mapped_file"`
|
||||
|
||||
if [ "${BEFORE_STR}" == "${AFTER_STR}" ]; then
|
||||
echo "TEST OK."
|
||||
else
|
||||
echo "TEST NG."
|
||||
echo "${BEFORE_STR}"
|
||||
echo "${AFTER_STR}"
|
||||
fi
|
||||
|
||||
rm -f ./tmp
|
||||
|
||||
echo ""
|
||||
echo "*** LTP"
|
||||
# mmap01 - 09, 12 - 15
|
||||
for i in `seq -f "%02g" 1 1 9` `seq -f "%02g" 12 1 15` ; do
|
||||
$MCEXEC $LTPBIN/mmap$i
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "*** ostest, check ok"
|
||||
for i in 0 2 4 6 10 11 32 34 36 38 40 41 42 43 48 ; do
|
||||
echo a > ./tmp
|
||||
$MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp \
|
||||
| grep "RESULT: ok" > /dev/null
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo "[OK] mmap_file $i"
|
||||
else
|
||||
echo "[NG] mmap_file $i"
|
||||
fi
|
||||
rm -f ./tmp
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "*** otest, check mmap error."
|
||||
for i in 8 9 `seq 16 1 31` ; do
|
||||
echo a > ./tmp
|
||||
$MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp \
|
||||
| grep "RESULT: mmap error." > /dev/null
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo "[OK] mmap_file $i"
|
||||
else
|
||||
echo "[NG] mmap_file $i"
|
||||
fi
|
||||
rm -f ./tmp
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "*** oetest, check page fault"
|
||||
for i in 1 3 5 7 12 13 14 15 33 35 37 39 44 45 46 47 ; do
|
||||
echo a > ./tmp
|
||||
$MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
if [ $? -eq 139 ] ; then
|
||||
echo "[OK] mmap_file $i"
|
||||
else
|
||||
echo "[NG] mmap_file $i"
|
||||
fi
|
||||
rm -f ./tmp
|
||||
done
|
||||
|
||||
rm -f core.* mccore-filemap_sigbus.* mccore-test_mck.*
|
||||
|
||||
14
test/issues/1422/Makefile
Normal file
14
test/issues/1422/Makefile
Normal 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 -Wl,-rpath=$(MCK_DIR)/lib64
|
||||
|
||||
all:
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) get_rusage.c -o get_rusage
|
||||
$(CC) $(CFLAGS) filemap_sigbus.c -o filemap_sigbus
|
||||
|
||||
test: all
|
||||
./C1422.sh
|
||||
|
||||
clean:
|
||||
rm -f get_rusage filemap_sigbus
|
||||
31
test/issues/1422/README
Normal file
31
test/issues/1422/README
Normal file
@ -0,0 +1,31 @@
|
||||
【Issue#1422 動作確認】
|
||||
□ テスト内容
|
||||
1. ファイルマップのEOFを超えたアクセスでSIGBUSが発生した場合に、
|
||||
memory_stat_mapped_fileがマイナスにならないことを確認する。
|
||||
2. ファイルマップ機能が正常に動作することを、LTPの以下のテストで確認する。
|
||||
mmap01 mmap01
|
||||
mmap02 mmap02
|
||||
mmap03 mmap03
|
||||
mmap04 mmap04
|
||||
mmap05 mmap05
|
||||
mmap06 mmap06
|
||||
mmap07 mmap07
|
||||
mmap08 mmap08
|
||||
mmap09 mmap09
|
||||
mmap12 mmap12
|
||||
mmap13 mmap13
|
||||
mmap14 mmap14
|
||||
mmap15 mmap15
|
||||
3. ファイルマップ機能が正常に動作することを、ostestの mmap_fileで確認する。
|
||||
|
||||
□ 実行手順
|
||||
$ make test
|
||||
|
||||
McKernelのインストール先や、OSTEST, LTPの配置場所は、
|
||||
$HOME/.mck_test_config を参照している。
|
||||
.mck_test_config は、McKernelをビルドした際に生成されるmck_test_config.sample ファイルを
|
||||
$HOMEにコピーし、適宜編集する。
|
||||
|
||||
□ 実行結果
|
||||
result.log を参照。
|
||||
すべての項目にPASSしていることを確認。
|
||||
49
test/issues/1422/filemap_sigbus.c
Normal file
49
test/issues/1422/filemap_sigbus.c
Normal file
@ -0,0 +1,49 @@
|
||||
/* filemap_sigbus.c COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret = -1;
|
||||
int fd = -1;
|
||||
int i = 0;
|
||||
unsigned long *buf = NULL;
|
||||
const long pgsize = sysconf(_SC_PAGESIZE);
|
||||
|
||||
if (argc != 2) {
|
||||
printf("args invalid.\n");
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fd = open(argv[1], O_RDWR);
|
||||
if (fd == -1) {
|
||||
perror("open");
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf = (unsigned long *)mmap(0, 3 * pgsize, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE, fd, 0);
|
||||
if (buf == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Generate SIGBUS */
|
||||
for (i = 0; i < 3 * pgsize / sizeof(unsigned long); i++) {
|
||||
buf[i] = i;
|
||||
}
|
||||
|
||||
munmap(buf, 3 * pgsize);
|
||||
|
||||
close(fd);
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
109
test/issues/1422/get_rusage.c
Normal file
109
test/issues/1422/get_rusage.c
Normal file
@ -0,0 +1,109 @@
|
||||
/* get_rusage.c COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ihklib.h>
|
||||
#include <ihk/ihk_rusage.h>
|
||||
|
||||
static void usage(char *cmd)
|
||||
{
|
||||
printf("Usage:\n");
|
||||
printf(" %s <os_number>\n", cmd);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int os_num = 0;
|
||||
int ret = -1;
|
||||
int i = 0;
|
||||
int nonzero = 0;
|
||||
struct ihk_os_rusage mck_rusage;
|
||||
|
||||
if (argc != 2) {
|
||||
usage(argv[0]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
os_num = atoi(argv[1]);
|
||||
if (os_num < 0 || 63 < os_num) {
|
||||
printf("Invalid argument 1 os_num.\n");
|
||||
usage(argv[0]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(&mck_rusage, 0, sizeof(mck_rusage));
|
||||
ret = ihk_os_getrusage(os_num, &mck_rusage, sizeof(mck_rusage));
|
||||
if (ret) {
|
||||
perror("ihk_os_getrusage()");
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf("show rusage:\n");
|
||||
nonzero = 0;
|
||||
for (i = 0; i < IHK_MAX_NUM_PGSIZES; i++) {
|
||||
if (mck_rusage.memory_stat_rss[i] != 0) {
|
||||
printf(" memory_stat_rss[%d] : 0x%lx\n", i,
|
||||
mck_rusage.memory_stat_rss[i]);
|
||||
nonzero = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (nonzero == 0) {
|
||||
printf(" memory_stat_rss is all 0x0\n");
|
||||
}
|
||||
|
||||
nonzero = 0;
|
||||
for (i = 0; i < IHK_MAX_NUM_PGSIZES; i++) {
|
||||
if (mck_rusage.memory_stat_mapped_file[i] != 0) {
|
||||
printf(" memory_stat_mapped_file[%d] : 0x%lx\n", i,
|
||||
mck_rusage.memory_stat_mapped_file[i]);
|
||||
nonzero = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (nonzero == 0) {
|
||||
printf(" memory_stat_mapped_file is all 0x0\n");
|
||||
}
|
||||
|
||||
printf(" memory_max_usage : 0x%lx\n", mck_rusage.memory_max_usage);
|
||||
printf(" memory_kmem_usage : 0x%lx\n", mck_rusage.memory_kmem_usage);
|
||||
printf(" memory_kmem_max_usage : 0x%lx\n",
|
||||
mck_rusage.memory_kmem_max_usage);
|
||||
|
||||
nonzero = 0;
|
||||
for (i = 0; i < IHK_MAX_NUM_NUMA_NODES; i++) {
|
||||
if (mck_rusage.memory_numa_stat[i] != 0) {
|
||||
printf(" memory_numa_stat[%d] : 0x%lx\n", i,
|
||||
mck_rusage.memory_numa_stat[i]);
|
||||
nonzero = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (nonzero == 0) {
|
||||
printf(" memory_numa_stat is all 0x0\n");
|
||||
}
|
||||
|
||||
printf(" cpuacct_stat_system : 0x%lx\n",
|
||||
mck_rusage.cpuacct_stat_system);
|
||||
printf(" cpuacct_stat_user : 0x%lx\n", mck_rusage.cpuacct_stat_user);
|
||||
printf(" cpuacct_usage : 0x%lx\n", mck_rusage.cpuacct_usage);
|
||||
|
||||
nonzero = 0;
|
||||
for (i = 0; i < IHK_MAX_NUM_CPUS; i++) {
|
||||
if (mck_rusage.cpuacct_usage_percpu[i] != 0) {
|
||||
printf(" cpuacct_usage_percpu[%d] : 0x%lx\n", i,
|
||||
mck_rusage.cpuacct_usage_percpu[i]);
|
||||
nonzero = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (nonzero == 0) {
|
||||
printf(" cpuacct_usage_percpu is all 0x0\n");
|
||||
}
|
||||
|
||||
printf(" num_threads : 0x%x\n", mck_rusage.num_threads);
|
||||
printf(" max_num_threads : 0x%x\n", mck_rusage.max_num_threads);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
105
test/issues/1422/result.log
Normal file
105
test/issues/1422/result.log
Normal file
@ -0,0 +1,105 @@
|
||||
cc -g -O0 -Wall -I/root/mck/target/include -L/root/mck/target/lib64 -lihk -Wl,-rpath=/root/mck/target/lib64 get_rusage.c -o get_rusage
|
||||
cc -g -O0 -Wall -I/root/mck/target/include filemap_sigbus.c -o filemap_sigbus
|
||||
./C1422.sh
|
||||
mcstop+release.sh ... done
|
||||
mcreboot.sh -c 12-15 -m 512M@4 ... done
|
||||
|
||||
*** get_rusage test
|
||||
./C1422.sh: line 12: 453200 Bus error (core dumped) $MCEXEC ./filemap_sigbus ./tmp
|
||||
TEST OK.
|
||||
|
||||
*** LTP
|
||||
mmap01 1 TPASS : Functionality of mmap() successful
|
||||
mmap02 1 TPASS : Functionality of mmap() successful
|
||||
mmap03 1 TPASS : mmap() functionality is correct
|
||||
mmap04 1 TPASS : Functionality of mmap() successful
|
||||
mmap05 1 TPASS : Got SIGSEGV as expected
|
||||
mmap06 1 TPASS : mmap failed with EACCES
|
||||
mmap07 1 TPASS : mmap failed with EACCES
|
||||
mmap08 1 TPASS : mmap failed with EBADF
|
||||
mmap09 1 TPASS : ftruncate mmaped file to a smaller size
|
||||
mmap09 2 TPASS : ftruncate mmaped file to a larger size
|
||||
mmap09 3 TPASS : ftruncate mmaped file to 0 size
|
||||
tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s
|
||||
mmap12.c:103: INFO: All pages are present
|
||||
mmap12.c:127: PASS: File mapped properly
|
||||
|
||||
Summary:
|
||||
passed 1
|
||||
failed 0
|
||||
skipped 0
|
||||
warnings 0
|
||||
mmap13 1 TPASS : Got SIGBUS as expected
|
||||
mmap14 1 TPASS : Functionality of mmap() successful
|
||||
mmap15 1 TPASS : mmap into high region failed as expected: errno=ENOMEM(12): Cannot allocate memory
|
||||
|
||||
*** ostest, check ok
|
||||
[OK] mmap_file 0
|
||||
[OK] mmap_file 2
|
||||
[OK] mmap_file 4
|
||||
[OK] mmap_file 6
|
||||
[OK] mmap_file 10
|
||||
[OK] mmap_file 11
|
||||
[OK] mmap_file 32
|
||||
[OK] mmap_file 34
|
||||
[OK] mmap_file 36
|
||||
[OK] mmap_file 38
|
||||
[OK] mmap_file 40
|
||||
[OK] mmap_file 41
|
||||
[OK] mmap_file 42
|
||||
[OK] mmap_file 43
|
||||
[OK] mmap_file 48
|
||||
|
||||
*** otest, check mmap error.
|
||||
[OK] mmap_file 8
|
||||
[OK] mmap_file 9
|
||||
[OK] mmap_file 16
|
||||
[OK] mmap_file 17
|
||||
[OK] mmap_file 18
|
||||
[OK] mmap_file 19
|
||||
[OK] mmap_file 20
|
||||
[OK] mmap_file 21
|
||||
[OK] mmap_file 22
|
||||
[OK] mmap_file 23
|
||||
[OK] mmap_file 24
|
||||
[OK] mmap_file 25
|
||||
[OK] mmap_file 26
|
||||
[OK] mmap_file 27
|
||||
[OK] mmap_file 28
|
||||
[OK] mmap_file 29
|
||||
[OK] mmap_file 30
|
||||
[OK] mmap_file 31
|
||||
|
||||
*** oetest, check page fault
|
||||
./C1422.sh: line 60: 453714 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 1
|
||||
./C1422.sh: line 60: 453724 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 3
|
||||
./C1422.sh: line 60: 453734 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 5
|
||||
./C1422.sh: line 60: 453744 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 7
|
||||
./C1422.sh: line 60: 453754 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 12
|
||||
./C1422.sh: line 60: 453764 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 13
|
||||
./C1422.sh: line 60: 453774 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 14
|
||||
./C1422.sh: line 60: 453784 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 15
|
||||
./C1422.sh: line 60: 453794 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 33
|
||||
./C1422.sh: line 60: 453804 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 35
|
||||
./C1422.sh: line 60: 453814 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 37
|
||||
./C1422.sh: line 60: 453824 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 39
|
||||
./C1422.sh: line 60: 453836 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 44
|
||||
./C1422.sh: line 60: 453846 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 45
|
||||
./C1422.sh: line 60: 453856 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 46
|
||||
./C1422.sh: line 60: 453866 Segmentation fault (core dumped) $MCEXEC $TESTMCK -s mmap_file -n $i -- -f ./tmp > /dev/null
|
||||
[OK] mmap_file 47
|
||||
Reference in New Issue
Block a user