syscall: the signal received during system call processing is not processed.

Refs: #1176
Fujitsu: POSTK_DEBUG_TEMP_FIX_56
Change-Id: I410160ccbcef3ef49a0e37611a608bc87c97e63b
This commit is contained in:
Tomoki Shirasawa
2018-09-07 14:54:45 +09:00
committed by Masamichi Takagi
parent e4da71010c
commit 5e760db417
10 changed files with 485 additions and 22 deletions

View File

@ -1001,6 +1001,11 @@ getsigpending(struct thread *thread, int delflag){
struct sig_pending * struct sig_pending *
hassigpending(struct thread *thread) hassigpending(struct thread *thread)
{ {
if (list_empty(&thread->sigpending) &&
list_empty(&thread->sigcommon->sigpending)) {
return NULL;
}
return getsigpending(thread, 0); return getsigpending(thread, 0);
} }
@ -1057,6 +1062,11 @@ check_signal(unsigned long rc, void *regs0, int num)
goto out; goto out;
} }
if (list_empty(&thread->sigpending) &&
list_empty(&thread->sigcommon->sigpending)) {
goto out;
}
for(;;){ for(;;){
pending = getsigpending(thread, 1); pending = getsigpending(thread, 1);
if(!pending) { if(!pending) {

View File

@ -3150,11 +3150,11 @@ void spin_sleep_or_schedule(void)
} }
ihk_mc_spinlock_unlock(&thread->spin_sleep_lock, irqstate); ihk_mc_spinlock_unlock(&thread->spin_sleep_lock, irqstate);
#ifdef POSTK_DEBUG_TEMP_FIX_56 /* in futex_wait() signal handring fix. */ if ((!list_empty(&thread->sigpending) ||
if (hassigpending(cpu_local_var(current))) { !list_empty(&thread->sigcommon->sigpending)) &&
hassigpending(thread)) {
woken = 1; woken = 1;
} }
#endif /* POSTK_DEBUG_TEMP_FIX_56 */
if (woken) { if (woken) {
return; return;

View File

@ -9523,11 +9523,8 @@ set_cputime(int mode)
long syscall(int num, ihk_mc_user_context_t *ctx) long syscall(int num, ihk_mc_user_context_t *ctx)
{ {
long l; long l;
#if !defined(POSTK_DEBUG_TEMP_FIX_60) && !defined(POSTK_DEBUG_TEMP_FIX_56) struct cpu_local_var *v = get_this_cpu_local_var();
struct thread *thread = cpu_local_var(current); struct thread *thread = v->current;
#else /* !defined(POSTK_DEBUG_TEMP_FIX_60) && !defined(POSTK_DEBUG_TEMP_FIX_56) */
struct thread *thread = cpu_local_var(current);
#endif /* !defined(POSTK_DEBUG_TEMP_FIX_60) && !defined(POSTK_DEBUG_TEMP_FIX_56) */
#ifdef DISABLE_SCHED_YIELD #ifdef DISABLE_SCHED_YIELD
if (num != __NR_sched_yield) if (num != __NR_sched_yield)
@ -9629,22 +9626,9 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
} }
#endif // PROFILE_ENABLE #endif // PROFILE_ENABLE
#if defined(POSTK_DEBUG_TEMP_FIX_60) && defined(POSTK_DEBUG_TEMP_FIX_56) if (v->flags & CPU_FLAG_NEED_RESCHED) {
check_need_resched();
#elif defined(POSTK_DEBUG_TEMP_FIX_60) /* sched_yield called check_signal fix. */
if (num != __NR_futex) {
check_need_resched(); check_need_resched();
} }
#elif defined(POSTK_DEBUG_TEMP_FIX_56) /* in futex_wait() signal handring fix. */
if (num != __NR_sched_yield) {
check_need_resched();
}
#else /* POSTK_DEBUG_TEMP_FIX_60 && POSTK_DEBUG_TEMP_FIX_56 */
if (num != __NR_sched_yield &&
num != __NR_futex) {
check_need_resched();
}
#endif /* POSTK_DEBUG_TEMP_FIX_60 && POSTK_DEBUG_TEMP_FIX_56 */
if (!list_empty(&thread->sigpending) || if (!list_empty(&thread->sigpending) ||
!list_empty(&thread->sigcommon->sigpending)) { !list_empty(&thread->sigcommon->sigpending)) {

136
test/issues/1176/C1176.sh Normal file
View File

@ -0,0 +1,136 @@
#!/bin/sh
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"
USELTP=1
USEOSTEST=1
################################################################################
BINDIR=
SBINDIR=
OSTESTDIR=
LTPDIR=
LTPBIN=
MCEXEC=
TESTMCK=
if [ -f $HOME/mck_test_config ]; then
. $HOME/mck_test_config
elif [ -f ../../../mck_test_config.sample ]; then
. ../../../mck_test_config.sample
else
BIN=
SBIN=
OSTEST=
LTP=
fi
#-------------------------------------------------------------------------------
if [ "x$BIN" = x ]; then
if [ -f ../../../config.h ]; then
str=`grep "^#define BINDIR " ../../../config.h | head -1 | sed 's/^#define BINDIR /BINDIR=/'`
eval $str
fi
else
BINDIR="$BIN"
fi
if [ "x$SBIN" = x ]; then
if [ -f ../../../Makefile ]; then
str=`grep ^SBINDIR ../../../Makefile | head -1 | sed 's/ //g'`
eval $str
fi
else
SBINDIR="$SBIN"
fi
if [ ! -x "$BINDIR/mcexec" ]; then
echo no mckernel found $BINDIR >&2
exit 1
fi
MCEXEC="$BINDIR/mcexec"
#-------------------------------------------------------------------------------
if [ "x$USELTP" != x ]; then
if [ "x$LTP" = x ]; then
if [ -f "$HOME/ltp/testcases/bin/fork01" ]; then
LTPDIR="$HOME/ltp"
fi
else
LTPDIR="$LTP"
fi
if [ ! -x "$LTPDIR/testcases/bin/fork01" ]; then
echo no LTP found $LTPDIR >&2
exit 1
fi
LTPBIN="$LTPDIR/testcases/bin"
fi
#-------------------------------------------------------------------------------
if [ "x$USEOSTEST" != x ]; then
if [ "x$OSTEST" = x ]; then
if [ -f "$HOME/ostest/bin/test_mck" ]; then
OSTESTDIR="$HOME/ostest"
fi
else
OSTESTDIR="$OSTEST"
fi
if [ ! -x "$OSTESTDIR"/bin/test_mck ]; then
echo no ostest found $OSTESTDIR >&2
exit 1
fi
TESTMCK="$OSTESTDIR/bin/test_mck"
fi
#===============================================================================
if [ ! -x "$SBINDIR/mcstop+release.sh" ]; then
echo mcstop+release: not found >&2
exit 1
fi
echo -n "mcstop+release.sh ... "
sudo "$SBINDIR/mcstop+release.sh"
echo "done"
if lsmod | grep mcctrl > /dev/null 2>&1; then
echo mckernel shutdown failed >&2
exit 1
fi
if [ ! -x "$SBINDIR/mcreboot.sh" ]; then
echo mcreboot: not found >&2
exit 1
fi
echo -n "mcreboot.sh $BOOTPARAM ... "
sudo "$SBINDIR/mcreboot.sh" $BOOTPARAM
echo "done"
if ! lsmod | grep mcctrl > /dev/null 2>&1; then
echo mckernel boot failed >&2
exit 1
fi
################################################################################
"$MCEXEC" "$TESTMCK" -s getrusage -n 2 2>&1 | tee C1176T01.txt
if grep "RESULT: you need check rusage value" C1176T01.txt > /dev/null 2>&1;then
echo "*** C1176T01: OK"
else
echo "*** C1176T01: NG"
fi
"$MCEXEC" ./C1176T02
"$MCEXEC" ./C1176T03
"$MCEXEC" ./C1176T04
for i in kill01:05 kill12:06 pause02:07 sigaction01:08 ; do
tp=`echo $i|sed 's/:.*//'`
id=`echo $i|sed 's/.*://'`
$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 "*** C1176T$id: $tp OK ($ok)"
else
echo "*** C1176T$id: $tp NG (ok=$ok ng=%ng)"
fi
done

View File

@ -0,0 +1,67 @@
Script started on Tue Sep 11 14:51:16 2018
bash-4.2$ make test
gcc -g -Wall -o C1176T02 C1176T02.c
gcc -g -Wall -o C1176T03 C1176T03.c
gcc -g -Wall -o C1176T04 C1176T04.c
sh ./C1176.sh
mcstop+release.sh ... done
mcreboot.sh -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 ... done
TEST_SUITE: getrusage
TEST_NUMBER: 2
ARGS:
[parent before]
------------------------------
show_rusage():
ru_utime=0s + 582us
ru_stime=0s + 42089us
ru_maxrss=6316
------------------------------
[child before]
------------------------------
show_rusage():
ru_utime=0s + 6us
ru_stime=0s + 0us
ru_maxrss=14512
------------------------------
allocation memory 16777216 byte(16384 KiB)
alarm 2 seconds wait.
sleep 2 seconds wait.
free memory 16777216 byte(16384 KiB)
[child after]
------------------------------
show_rusage():
ru_utime=1s + 997934us
ru_stime=2s + 2895us
ru_maxrss=30900
------------------------------
[parent after]
------------------------------
show_rusage():
ru_utime=0s + 599us
ru_stime=4s + 44489us
ru_maxrss=30900
------------------------------
RESULT: you need check rusage value
*** C1176T01: OK
*** C1176T02: OK
*** C1176T03: OK
parent call sleep
child call sleep
parent return from sleep
child return from sleep
*** C1176T04: OK
kill01 1 TPASS : received expected signal 9
*** C1176T05: kill01 OK (1)
kill12 1 TPASS : Test passed
*** C1176T06: kill12 OK (1)
pause02 1 TPASS : pause was interrupted correctly
*** C1176T07: pause02 OK (1)
sigaction01 1 TPASS : SA_RESETHAND did not cause SA_SIGINFO to be cleared
sigaction01 2 TPASS : SA_RESETHAND was masked when handler executed
sigaction01 3 TPASS : sig has been masked because sa_mask originally contained sig
sigaction01 4 TPASS : siginfo pointer non NULL
*** C1176T08: sigaction01 OK (4)
bash-4.2$ exit
exit
Script done on Tue Sep 11 14:51:54 2018

View File

@ -0,0 +1,69 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
int sighandler;
void
sig(int s)
{
sighandler = 1;
}
int
main(int argc, char **argv)
{
pid_t pid;
int st;
if ((pid = fork()) == 0) {
struct sigaction act;
char ch;
int rc;
memset(&act, '\0', sizeof(act));
act.sa_handler = sig;
sigaction(SIGINT, &act, NULL);
rc = read(0, &ch, 1);
if (rc != -1 || errno != EINTR) {
exit(rc == -1 ? 1 : 2);
}
if (sighandler == 0) {
exit(3);
}
exit(0);
}
sleep(1);
kill(pid, SIGINT);
if (waitpid(pid, &st, 0) == -1) {
fprintf(stderr, "*** C1176T02: NG wait %d\n", errno);
exit(1);
}
if (WIFSIGNALED(st)) {
fprintf(stderr, "*** C1176T02: NG termsig %d\n", WTERMSIG(st));
exit(1);
}
if (WEXITSTATUS(st) == 1) {
fprintf(stderr, "*** C1176T02: NG BAD read\n");
exit(1);
}
else if (WEXITSTATUS(st) == 2) {
fprintf(stderr, "*** C1176T02: NG BAD read error\n");
exit(1);
}
else if (WEXITSTATUS(st) == 3) {
fprintf(stderr, "*** C1176T02: NG don't called sighandler\n");
exit(1);
}
else if (WEXITSTATUS(st) != 0) {
fprintf(stderr, "*** C1176T02: NG unknown\n");
exit(1);
}
fprintf(stderr, "*** C1176T02: OK\n");
exit(0);
}

View File

@ -0,0 +1,74 @@
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#include <linux/futex.h>
#include <sys/time.h>
#include <sys/syscall.h>
int sighandler;
void
sig(int s)
{
sighandler = 1;
}
int
main(int argc, char **argv)
{
pid_t pid;
int st;
if ((pid = fork()) == 0) {
struct sigaction act;
int wk;
int rc;
memset(&act, '\0', sizeof(act));
act.sa_handler = sig;
sigaction(SIGINT, &act, NULL);
wk = 0;
rc = syscall(SYS_futex, &wk, FUTEX_WAIT, 0, NULL, NULL, 0);
if (rc != -1 || errno != EINTR) {
exit(rc == -1 ? 1 : 2);
}
if (sighandler == 0) {
exit(3);
}
exit(0);
}
sleep(1);
kill(pid, SIGINT);
if (waitpid(pid, &st, 0) == -1) {
fprintf(stderr, "*** C1176T03: NG wait %d\n", errno);
exit(1);
}
if (WIFSIGNALED(st)) {
fprintf(stderr, "*** C1176T03: NG termsig %d\n", WTERMSIG(st));
exit(1);
}
if (WEXITSTATUS(st) == 1) {
fprintf(stderr, "*** C1176T03: NG BAD read\n");
exit(1);
}
else if (WEXITSTATUS(st) == 2) {
fprintf(stderr, "*** C1176T03: NG BAD read error\n");
exit(1);
}
else if (WEXITSTATUS(st) == 3) {
fprintf(stderr, "*** C1176T03: NG don't called sighandler\n");
exit(1);
}
else if (WEXITSTATUS(st) != 0) {
fprintf(stderr, "*** C1176T03: NG unknown\n");
exit(1);
}
fprintf(stderr, "*** C1176T03: OK\n");
exit(0);
}

View File

@ -0,0 +1,55 @@
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sched.h>
#include <errno.h>
int
main(int argc, char **argv)
{
pid_t pid;
cpu_set_t cpuset;
int st;
CPU_ZERO(&cpuset);
CPU_SET(1, &cpuset);
if (!(pid = fork())) {
if (sched_setaffinity(0, sizeof(cpuset), &cpuset)) {
fprintf(stderr, "*** C1176T04: NG\n");
exit(1);
}
fprintf(stderr, "child call sleep\n");
fflush(stderr);
sleep(1);
fprintf(stderr, "child return from sleep\n");
fflush(stderr);
exit(0);
}
if (sched_setaffinity(0, sizeof(cpuset), &cpuset)) {
fprintf(stderr, "*** C1176T04: NG\n");
exit(1);
}
fprintf(stderr, "parent call sleep\n");
fflush(stderr);
sleep(1);
fprintf(stderr, "parent return from sleep\n");
fflush(stderr);
if (waitpid(pid, &st, 0) == -1) {
fprintf(stderr, "*** C1176T04: NG %d\n", errno);
exit(1);
}
if (!WIFEXITED(st) || WEXITSTATUS(st)) {
fprintf(stderr, "*** C1176T04: NG %08x\n", st);
exit(1);
}
fprintf(stderr, "*** C1176T04: OK\n");
exit(0);
}

19
test/issues/1176/Makefile Normal file
View File

@ -0,0 +1,19 @@
CC=gcc
TARGET=C1176T02 C1176T03 C1176T04
all:: $(TARGET)
C1176T02: C1176T02.c
$(CC) -g -Wall -o $@ $^
C1176T03: C1176T03.c
$(CC) -g -Wall -o $@ $^
C1176T04: C1176T04.c
$(CC) -g -Wall -o $@ $^
test:: $(TARGET)
sh ./C1176.sh
clean::
rm -f $(TARGET) *.o

49
test/issues/1176/README Normal file
View File

@ -0,0 +1,49 @@
【Issue#1176 動作確認】
□ テスト内容
1. 指摘の現象が解消されていることを確認する。
C1176T01 指摘の現象が解消されていることを、テストプログラムを用いて確認
mcexec test_mck -s getrusage -n 2
2. 修正が正しく動作することをテストプログラムを用いて確認する。
変更は以下の3点である。
(1) システムコール出口で高速化のためシグナル処理を呼び出していなかったが、
ロック無しでシグナル受信を判定後に、シグナル処理を呼び出すようにした。
(2) futex_wait 処理で高速化のためシグナル受信の判定処理をしていなかったが、
ロック無しでシグナル受信を判定し、受信していた場合にfutex_wait
処理を脱出するようにした。(その後、システムコール出口でシグナルが
処理される)
(3) 高速化のためシステムコール出口での再スケジュール処理を呼び出して
いなかったが、ロック無しで再スケジュール要否を判定し、再スケジュールが
必要な場合は再スケジュール処理を行うよにした。
C1176T02 システムコールオフロード中にシグナル受信し、システムコールが中断
してシグナル処理されることを確認
C1176T03 futex_wait 処理中にシグナル受信し、futex_waitが中断してシグナルが
処理されることを確認
C1176T04 2つのプロセスを同一CPUに割り当てた状態で、各々1秒sleepするとき、
それぞれのプロセスが正しく処理されることを確認。
sleep完了後にシステムコール出口で再スケジュール処理が行われる
3. 修正が既存処理に影響しないことをLTPを用いて確認する。
シグナル関連処理(正常系)を中心にテストプログラムを選定した。
C1176T05 kill01: kill の基本機能の確認
C1176T06 kill12: kill, wait, signal の組み合わせ確認
C1176T07 pause02: pause の基本機能の確認
C1176T08 sigaction01: sigaction の基本機能の確認
□ 実行手順
$ make test
実行できない場合は、C1176.shの以下の行を適切に書き換えた後に実行。
BIN= mcexec が存在するパス
SBIN= mcreboot.sh が存在するパス
LTP= LTP が存在するパス
OSTEST= OSTEST が存在するパス
□ 実行結果
C1176.txt 参照。
全ての項目が OK となっていることを確認。