Register PPD and release_handler at the same time.

Fix that process will remain even if signal is received between PPD
registration and release_handler registration.

Refs: #1201
Fujitsu: POSTK_DEBUG_TEMP_FIX_64
Change-Id: I571781963578df8cedb327f19298f595cfb137a3
This commit is contained in:
Tomoki Shirasawa
2019-02-08 10:20:58 +09:00
parent f5023c9730
commit ff0395581c
10 changed files with 182 additions and 24 deletions

View File

@ -38,7 +38,6 @@
#define MCEXEC_UP_SEND_SIGNAL 0x30a02906 #define MCEXEC_UP_SEND_SIGNAL 0x30a02906
#define MCEXEC_UP_GET_CPU 0x30a02907 #define MCEXEC_UP_GET_CPU 0x30a02907
#define MCEXEC_UP_STRNCPY_FROM_USER 0x30a02908 #define MCEXEC_UP_STRNCPY_FROM_USER 0x30a02908
#define MCEXEC_UP_NEW_PROCESS 0x30a02909
#define MCEXEC_UP_GET_CRED 0x30a0290a #define MCEXEC_UP_GET_CRED 0x30a0290a
#define MCEXEC_UP_GET_CREDV 0x30a0290b #define MCEXEC_UP_GET_CREDV 0x30a0290b
#define MCEXEC_UP_GET_NODES 0x30a0290c #define MCEXEC_UP_GET_NODES 0x30a0290c
@ -230,10 +229,6 @@ struct signal_desc {
char info[128]; char info[128];
}; };
struct newprocess_desc {
int pid;
};
struct sys_mount_desc { struct sys_mount_desc {
char *dev_name; char *dev_name;
char *dir_name; char *dir_name;

View File

@ -389,21 +389,15 @@ static void release_handler(ihk_os_t os, void *param)
__FUNCTION__, info); __FUNCTION__, info);
} }
static long mcexec_newprocess(ihk_os_t os, static long mcexec_newprocess(ihk_os_t os, struct file *file)
struct newprocess_desc *__user udesc,
struct file *file)
{ {
struct newprocess_desc desc;
struct mcos_handler_info *info; struct mcos_handler_info *info;
if (copy_from_user(&desc, udesc, sizeof(struct newprocess_desc))) {
return -EFAULT;
}
info = new_mcos_handler_info(os, file); info = new_mcos_handler_info(os, file);
if (info == NULL) { if (info == NULL) {
return -ENOMEM; return -ENOMEM;
} }
info->pid = desc.pid; info->pid = task_tgid_vnr(current);
ihk_os_register_release_handler(file, release_handler, info); ihk_os_register_release_handler(file, release_handler, info);
ihk_os_set_mcos_private_data(file, info); ihk_os_set_mcos_private_data(file, info);
return 0; return 0;
@ -1720,12 +1714,14 @@ mcexec_getcredv(int __user *virt)
} }
int mcexec_create_per_process_data(ihk_os_t os, int mcexec_create_per_process_data(ihk_os_t os,
struct rpgtable_desc * __user rpt) struct rpgtable_desc * __user rpt,
struct file *file)
{ {
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os); struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
struct mcctrl_per_proc_data *ppd = NULL; struct mcctrl_per_proc_data *ppd = NULL;
int i; int i;
struct rpgtable_desc krpt; struct rpgtable_desc krpt;
long ret;
if (rpt && if (rpt &&
copy_from_user(&krpt, rpt, sizeof(krpt))) { copy_from_user(&krpt, rpt, sizeof(krpt))) {
@ -1745,6 +1741,10 @@ int mcexec_create_per_process_data(ihk_os_t os,
printk("%s: ERROR: allocating per-process data\n", __FUNCTION__); printk("%s: ERROR: allocating per-process data\n", __FUNCTION__);
return -ENOMEM; return -ENOMEM;
} }
if ((ret = mcexec_newprocess(os, file))) {
kfree(ppd);
return ret;
}
memset(ppd, 0, sizeof(struct mcctrl_per_proc_data)); /* debug */ memset(ppd, 0, sizeof(struct mcctrl_per_proc_data)); /* debug */
ppd->ud = usrdata; ppd->ud = usrdata;
@ -3159,7 +3159,7 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg,
case MCEXEC_UP_CREATE_PPD: case MCEXEC_UP_CREATE_PPD:
return mcexec_create_per_process_data(os, return mcexec_create_per_process_data(os,
(struct rpgtable_desc * __user)arg); (struct rpgtable_desc * __user)arg, file);
case MCEXEC_UP_GET_NODES: case MCEXEC_UP_GET_NODES:
return mcexec_get_nodes(os); return mcexec_get_nodes(os);
@ -3171,10 +3171,6 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg,
return mcexec_strncpy_from_user(os, return mcexec_strncpy_from_user(os,
(struct strncpy_from_user_desc *)arg); (struct strncpy_from_user_desc *)arg);
case MCEXEC_UP_NEW_PROCESS:
return mcexec_newprocess(os, (struct newprocess_desc *)arg,
file);
case MCEXEC_UP_OPEN_EXEC: case MCEXEC_UP_OPEN_EXEC:
return mcexec_open_exec(os, (char *)arg); return mcexec_open_exec(os, (char *)arg);

View File

@ -74,7 +74,6 @@ static struct ihk_os_user_call_handler mcctrl_uchs[] = {
{ .request = MCEXEC_UP_GET_CPUSET, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_GET_CPUSET, .func = mcctrl_ioctl },
{ .request = MCEXEC_UP_CREATE_PPD, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_CREATE_PPD, .func = mcctrl_ioctl },
{ .request = MCEXEC_UP_STRNCPY_FROM_USER, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_STRNCPY_FROM_USER, .func = mcctrl_ioctl },
{ .request = MCEXEC_UP_NEW_PROCESS, .func = mcctrl_ioctl },
{ .request = MCEXEC_UP_PREPARE_DMA, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_PREPARE_DMA, .func = mcctrl_ioctl },
{ .request = MCEXEC_UP_FREE_DMA, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_FREE_DMA, .func = mcctrl_ioctl },
{ .request = MCEXEC_UP_OPEN_EXEC, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_OPEN_EXEC, .func = mcctrl_ioctl },

View File

@ -3807,7 +3807,6 @@ gettid_out:
/* Child process */ /* Child process */
case 0: { case 0: {
int ret = 1; int ret = 1;
struct newprocess_desc npdesc;
struct rpgtable_desc rpt; struct rpgtable_desc rpt;
ischild = 1; ischild = 1;
@ -3879,9 +3878,6 @@ fork_child_sync_pipe:
fork_sync_top = NULL; fork_sync_top = NULL;
pthread_mutex_init(&fork_sync_mutex, NULL); pthread_mutex_init(&fork_sync_mutex, NULL);
npdesc.pid = getpid();
ioctl(fd, MCEXEC_UP_NEW_PROCESS, &npdesc);
/* TODO: does the forked thread run in a pthread context? */ /* TODO: does the forked thread run in a pthread context? */
while (getppid() != 1 && while (getppid() != 1 &&
fs->success == 0) { fs->success == 0) {

View File

@ -75,6 +75,20 @@ if ((USEOSTEST)); then
TESTMCK="$OSTEST/bin/test_mck" TESTMCK="$OSTEST/bin/test_mck"
fi fi
if ((USESTRESSTEST)); then
if [[ -z "$STRESS_TEST" ]]; then
if [[ -f "$HOME/stress_test/bin/signalonfork" ]]; then
STRESS_TEST="$HOME/stress_test"
fi
fi
if [[ ! -x "$STRESS_TEST/bin/signalonfork" ]]; then
echo no STRESS_TEST found $STRESS_TEST >&2
exit 1
fi
STRESSTESTBIN="$STRESS_TEST/bin"
fi
# compat variables # compat variables
BINDIR="$BIN" BINDIR="$BIN"
SBINDIR="$SBIN" SBINDIR="$SBIN"

61
test/issues/1201/C1201.sh Normal file
View File

@ -0,0 +1,61 @@
#!/bin/sh
USELTP=1
USEOSTEST=0
USESTRESSTEST=1
MCREBOOT=0
MCSTOP=0
. ../../common.sh
################################################################################
ng=0
org="`pwd`"
(
cd "$STRESSTESTBIN"
rm -f config.sh.bak
if [ -f config.sh ]; then
mv config.sh config.sh.bak
sed -e '/^MCKDIR=/d' config.sh.bak > config.sh
fi
echo "MCKDIR=\"$MCK_DIR\"" >> config.sh
if ! grep ^MCREBOOTOPTION= config.sh > /dev/null 2>&1; then
echo "MCREBOOTOPTION=\"$BOOTPARAM\"" >> config.sh
fi
rm -f "$org/C1201T01.log"
echo C1201T01 START
for i in {1..100}; do
sudo ./mck-stop.sh >> "$org/C1201T01.log" 2>&1
sudo ./mck-boot.sh >> "$org/C1201T01.log" 2>&1
./mck-mcexec.sh ./killit -np 8 -t 2000 - ./signalonfork \
-nosignal >> "$org/C1201T01.log" 2>&1
if [ "X$?" = X0 ]; then
echo -n .
else
echo
echo C1201T01: NG see C1201T01.log
ng=1
break
fi
done
if [ $ng = 0 ]; then
echo
echo C1201T01: OK
fi
if [ -f config.sh.bak ]; then
mv config.sh.bak config.sh
fi
)
for i in fork01:02 fork02:03 fork03:04 fork04:05 fork07:06 fork08:07 fork09:08 \
fork10:09 fork11:10; do
tp=`echo $i|sed 's/:.*//'`
id=`echo $i|sed 's/.*://'`
sudo $MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt
ok=`grep TPASS $tp.txt | wc -l`
ng=`grep TFAIL $tp.txt | wc -l`
if [ $ng = 0 ]; then
echo "*** C1201T$id: $tp OK ($ok)"
else
echo "*** C1201T$id: $tp NG (ok=$ok ng=%ng)"
fi
done

View File

@ -0,0 +1,53 @@
Script started on Tue Jan 22 12:16:17 2019
bash-4.2$ make test
sh ./C1201.sh
C1201T01 START
....................................................................................................
C1201T01: OK
fork01 1 TPASS : fork() returned 22030
fork01 2 TPASS : child pid and fork() return agree: 22030
*** C1201T02: fork01 OK (2)
fork02 0 TINFO : Inside parent
fork02 0 TINFO : Inside child
fork02 0 TINFO : exit status of wait 0
fork02 1 TPASS : test 1 PASSED
*** C1201T03: fork02 OK (1)
fork03 0 TINFO : process id in parent of child from fork : 22181
fork03 1 TPASS : test 1 PASSED
*** C1201T04: fork03 OK (1)
fork04 1 TPASS : Env var TERM unchanged after fork(): xterm
fork04 2 TPASS : Env var NoTSetzWq unchanged after fork(): getenv() does not find variable set
fork04 3 TPASS : Env var TESTPROG unchanged after fork(): FRKTCS04
*** C1201T05: fork04 OK (3)
fork07 0 TINFO : Forking 100 children
fork07 0 TINFO : Forked all 100 children, now collecting
fork07 0 TINFO : Collected all 100 children
fork07 1 TPASS : 100/100 children read correctly from an inheritted fd
*** C1201T06: fork07 OK (1)
fork08 0 TINFO : parent forksval: 1
fork08 0 TINFO : parent forksval: 2
fork08 0 TINFO : exit status of wait expected 0 got 0
fork08 1 TPASS : parent test PASSED
fork08 0 TINFO : second child got char: b
fork08 1 TPASS : Test passed in childnumber 2
fork08 0 TINFO : exit status of wait expected 0 got 0
fork08 2 TPASS : parent test PASSED
fork08 0 TINFO : exit status of wait expected 0 got 0
fork08 3 TPASS : parent test PASSED
fork08 0 TINFO : Number of processes forked is 2
*** C1201T07: fork08 OK (4)
fork09 0 TINFO : OPEN_MAX is 1024
fork09 0 TINFO : first file descriptor is 12
fork09 0 TINFO : Parent reporting 1023 files open
fork09 0 TINFO : Child opened new file #1023
fork09 1 TPASS : test 1 PASSED
*** C1201T08: fork09 OK (1)
fork10 0 TINFO : fork child A
fork10 1 TPASS : test 1 PASSED
*** C1201T09: fork10 OK (1)
fork11 1 TPASS : fork test passed, 100 processes
*** C1201T10: fork11 OK (1)
bash-4.2$ exit
exit
Script done on Tue Jan 22 12:52:39 2019

View File

@ -0,0 +1,9 @@
TARGET=
all:: $(TARGET)
test:: $(TARGET)
sh ./C1201.sh
clean::
rm -f *.o $(TARGET)

34
test/issues/1201/README Normal file
View File

@ -0,0 +1,34 @@
【Issue#1201 動作確認】
□ テスト内容
テスト内容は以下の通りである。
1. Issue 指摘事項の再現確認
C1201T01 stress-6-1-signalonfork-001 を 100 回連続で正常終了することを確認。
対策前は 20 回程度の連続実行で確実に再現するため、100 回の連続実行
で発生しなければ対策されたと判断する。
2. LTP を用いて既存処理に影響しないことを確認
プロセス生成処理関連を変更したため、fork のテストを選定した。
C1201T02 fork01 が PASS すること
C1201T03 fork02 が PASS すること
C1201T04 fork03 が PASS すること
C1201T05 fork04 が PASS すること
C1201T06 fork07 が PASS すること
C1201T07 fork08 が PASS すること
C1201T08 fork09 が PASS すること
C1201T09 fork10 が PASS すること
C1201T10 fork11 が PASS すること
□ 実行手順
$ make test
McKernelのインストール先や LTP の配置場所は、$HOME/.mck_test_config を
参照する。.mck_test_config は、McKernel を ビルドした際に生成される
mck_test_config.sample ファイルを $HOME に コピーし、適宜編集すること。
また、C1201.sh の以下の指定を適宜変更すること。
STRESSTESTDIR= ストレステストが存在するパス。
($HOME/stress_test の場合は変更不要)
□ 実行結果
C1201.txt 参照。
すべての項目をPASSしていることを確認。

View File

@ -4,5 +4,6 @@
: ${SBIN:=@prefix@/sbin} : ${SBIN:=@prefix@/sbin}
: ${OSTEST:=} : ${OSTEST:=}
: ${LTP:=} : ${LTP:=}
: ${STRESS_TEST:=}
: ${BOOTPARAM:=-c 1-7,9-15,17-23,25-31 -m 10G@0,10G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24} : ${BOOTPARAM:=-c 1-7,9-15,17-23,25-31 -m 10G@0,10G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24}
: ${MCKERNEL_VERSION:=@MCKERNEL_VERSION@} : ${MCKERNEL_VERSION:=@MCKERNEL_VERSION@}