<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-size:small"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Jun 16, 2019 at 7:08 AM Jan Stancek <<a href="mailto:jstancek@redhat.com">jstancek@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
----- Original Message -----<br>
> +static void setup(void)<br>
> +{<br>
> +     sigset_t sigusr1;<br>
> +     pthread_t defunct_thread;<br>
> +<br>
> +     sigemptyset(&sigusr1);<br>
> +     sigaddset(&sigusr1, SIGUSR1);<br>
> +     pthread_sigmask(SIG_BLOCK, &sigusr1, NULL);<br>
> +<br>
> +     parent_tgid = getpid();<br>
> +     parent_tid = sys_gettid();<br>
> +<br>
> +     SAFE_PTHREAD_CREATE(&child_thread, NULL, child_thread_func, NULL);<br>
> +<br>
> +     TST_CHECKPOINT_WAIT(0);<br>
<br>
I'm seeing reports of this test failing on s390x:<br>
<br>
st_test.c:1096: INFO: Timeout per run is 0h 05m 00s<br>
tgkill03.c:92: PASS: Invalid tgid failed as expected: EINVAL<br>
tgkill03.c:92: PASS: Invalid tid failed as expected: EINVAL<br>
tgkill03.c:92: PASS: Invalid signal failed as expected: EINVAL<br>
tgkill03.c:96: FAIL: Defunct tid should have failed with ESRCH: SUCCESS<br>
tgkill03.c:92: PASS: Defunct tgid failed as expected: ESRCH<br>
tgkill03.c:99: PASS: Valid tgkill call succeeded<br>
<br>
and I suspect this piece:<br>
<br>
> +<br>
> +     SAFE_PTHREAD_CREATE(&defunct_thread, NULL, defunct_thread_func, NULL);<br>
> +<br>
> +     SAFE_PTHREAD_JOIN(defunct_thread, NULL);<br>
> +}<br>
<br>
glibc pthread_join() waits for CLONE_CHILD_CLEARTID to clear tid,<br>
and then resumes. Which kernel does at:<br>
  do_exit<br>
    exit_mm<br>
      mm_release<br>
        put_user(0, tsk->clear_child_tid);<br>
<br>
so there's still work to be done after that, and I suspect tid is still valid<br>
while that happens.<br>
<br>
My first idea: wait until /proc/pid/task/<tid> disappears.<br></blockquote><div><br></div><div class="gmail_default" style="font-size:small">The anaysis is probably right, but this idea doesn't work for me. Seems /proc/pid/task/<tid> is not the key point to confirm that tid has been clear.</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">I just have a try as below:</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small"><div class="gmail_default">===========<br class="gmail-Apple-interchange-newline"># for i in `seq 1000`; do echo "i = $i" && ./tgkill03 || break; done<br></div><div class="gmail_default">...</div>i = 96<br>tst_test.c:1112: INFO: Timeout per run is 0h 05m 00s<br>tgkill03.c:106: FAIL: Defunct tid should have failed with ESRCH: SUCCESS<br></div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">===========</div><div class="gmail_default" style="font-size:small">--- a/testcases/kernel/syscalls/tgkill/tgkill03.c<br>+++ b/testcases/kernel/syscalls/tgkill/tgkill03.c<br>@@ -5,6 +5,7 @@<br>  * Test simple tgkill() error cases.<br>  */<br> <br>+#include <stdio.h><br> #include <pthread.h><br> #include <pwd.h><br> #include <sys/types.h><br>@@ -19,6 +20,7 @@ static pid_t parent_tgid;<br> static pid_t parent_tid;<br> static pid_t child_tid;<br> static pid_t defunct_tid;<br>+char buf[1024];<br> <br> static const int invalid_pid = -1;<br> <br>@@ -35,6 +37,8 @@ static void *defunct_thread_func(void *arg)<br> {<br>        defunct_tid = sys_gettid();<br> <br>+       sprintf(buf, "/proc/pid/task/%d", defunct_tid);<br>+<br>        return arg;<br> }<br> <br>@@ -73,18 +77,23 @@ static const struct testcase {<br>        const int sig;<br>        const int err;<br> } testcases[] = {<br>-       { "Invalid tgid", &invalid_pid, &parent_tid, SIGUSR1, EINVAL },<br>-       { "Invalid tid", &parent_tgid, &invalid_pid, SIGUSR1, EINVAL },<br>-       { "Invalid signal", &parent_tgid, &parent_tid, -1, EINVAL },<br>+//     { "Invalid tgid", &invalid_pid, &parent_tid, SIGUSR1, EINVAL },<br>+//     { "Invalid tid", &parent_tgid, &invalid_pid, SIGUSR1, EINVAL },<br>+//     { "Invalid signal", &parent_tgid, &parent_tid, -1, EINVAL },<br>        { "Defunct tid", &parent_tgid, &defunct_tid, SIGUSR1, ESRCH },<br>-       { "Defunct tgid", &defunct_tid, &child_tid, SIGUSR1, ESRCH },<br>-       { "Valid tgkill call", &parent_tgid, &child_tid, SIGUSR1, 0 },<br>+//     { "Defunct tgid", &defunct_tid, &child_tid, SIGUSR1, ESRCH },<br>+//     { "Valid tgkill call", &parent_tgid, &child_tid, SIGUSR1, 0 },<br> };<br> <br> static void run(unsigned int i)<br> {<br>        const struct testcase *tc = &testcases[i];<br> <br>+       // debug code //<br>+       while (access(buf, F_OK) == 0) {<br>+               tst_res(TINFO, "Debug: %s still exist!", buf);<br>+       }<br>+<br>        TEST(sys_tgkill(*tc->tgid, *tc->tid, tc->sig));<br>        if (tc->err) {<br>                if (TST_RET < 0 && TST_ERR == tc->err)<br></div><div class="gmail_default" style="font-size:small"><br></div></div><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div>Regards,<br></div><div>Li Wang<br></div></div></div></div>