diff --git a/arch/x86_64/kernel/syscall.c b/arch/x86_64/kernel/syscall.c index bb513000..d1f2e438 100644 --- a/arch/x86_64/kernel/syscall.c +++ b/arch/x86_64/kernel/syscall.c @@ -1001,6 +1001,11 @@ getsigpending(struct thread *thread, int delflag){ struct sig_pending * hassigpending(struct thread *thread) { + if (list_empty(&thread->sigpending) && + list_empty(&thread->sigcommon->sigpending)) { + return NULL; + } + return getsigpending(thread, 0); } @@ -1057,6 +1062,11 @@ check_signal(unsigned long rc, void *regs0, int num) goto out; } + if (list_empty(&thread->sigpending) && + list_empty(&thread->sigcommon->sigpending)) { + goto out; + } + for(;;){ pending = getsigpending(thread, 1); if(!pending) { diff --git a/kernel/process.c b/kernel/process.c index 582631bd..fad3e910 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -3150,11 +3150,11 @@ void spin_sleep_or_schedule(void) } ihk_mc_spinlock_unlock(&thread->spin_sleep_lock, irqstate); -#ifdef POSTK_DEBUG_TEMP_FIX_56 /* in futex_wait() signal handring fix. */ - if (hassigpending(cpu_local_var(current))) { + if ((!list_empty(&thread->sigpending) || + !list_empty(&thread->sigcommon->sigpending)) && + hassigpending(thread)) { woken = 1; } -#endif /* POSTK_DEBUG_TEMP_FIX_56 */ if (woken) { return; diff --git a/kernel/syscall.c b/kernel/syscall.c index 97fb3bcc..7d22c8f8 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -9523,11 +9523,8 @@ set_cputime(int mode) long syscall(int num, ihk_mc_user_context_t *ctx) { long l; -#if !defined(POSTK_DEBUG_TEMP_FIX_60) && !defined(POSTK_DEBUG_TEMP_FIX_56) - struct thread *thread = cpu_local_var(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) */ + struct cpu_local_var *v = get_this_cpu_local_var(); + struct thread *thread = v->current; #ifdef DISABLE_SCHED_YIELD if (num != __NR_sched_yield) @@ -9629,22 +9626,9 @@ long syscall(int num, ihk_mc_user_context_t *ctx) } #endif // PROFILE_ENABLE -#if defined(POSTK_DEBUG_TEMP_FIX_60) && defined(POSTK_DEBUG_TEMP_FIX_56) - check_need_resched(); -#elif defined(POSTK_DEBUG_TEMP_FIX_60) /* sched_yield called check_signal fix. */ - if (num != __NR_futex) { + if (v->flags & CPU_FLAG_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) || !list_empty(&thread->sigcommon->sigpending)) { diff --git a/test/issues/1176/C1176.sh b/test/issues/1176/C1176.sh new file mode 100644 index 00000000..f9af578d --- /dev/null +++ b/test/issues/1176/C1176.sh @@ -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 diff --git a/test/issues/1176/C1176.txt b/test/issues/1176/C1176.txt new file mode 100644 index 00000000..fd6a08cd --- /dev/null +++ b/test/issues/1176/C1176.txt @@ -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 diff --git a/test/issues/1176/C1176T02.c b/test/issues/1176/C1176T02.c new file mode 100644 index 00000000..b909ffd2 --- /dev/null +++ b/test/issues/1176/C1176T02.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +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); +} diff --git a/test/issues/1176/C1176T03.c b/test/issues/1176/C1176T03.c new file mode 100644 index 00000000..2b8c8b65 --- /dev/null +++ b/test/issues/1176/C1176T03.c @@ -0,0 +1,74 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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); +} diff --git a/test/issues/1176/C1176T04.c b/test/issues/1176/C1176T04.c new file mode 100644 index 00000000..aeea211a --- /dev/null +++ b/test/issues/1176/C1176T04.c @@ -0,0 +1,55 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +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); +} diff --git a/test/issues/1176/Makefile b/test/issues/1176/Makefile new file mode 100644 index 00000000..38fa1729 --- /dev/null +++ b/test/issues/1176/Makefile @@ -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 diff --git a/test/issues/1176/README b/test/issues/1176/README new file mode 100644 index 00000000..6d8493e0 --- /dev/null +++ b/test/issues/1176/README @@ -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 となっていることを確認。