[LTP] [PATCH] syscalls/gettid02: fix s390x and couple races

Li Wang liwang@redhat.com
Fri Oct 20 11:22:51 CEST 2023


On Thu, Oct 19, 2023 at 7:40 PM Jan Stancek <jstancek@redhat.com> wrote:

> s390x is big endian where sizeof(int) == 4 and sizeof(void *) == 8.
> This test currently fails on s390x because in pthread_join, "&tids[i]"
> is treated as "void**" and due to different type size it writes over
> 2 entries of tids[] array. So for small tid values test reports:
>         gettid02.c:29: TPASS: Expect: parent ID (14048) differs from
> thread[0] ID (14049)
>         gettid02.c:29: TPASS: Expect: parent ID (14048) differs from
> thread[1] ID (14050)
>         gettid02.c:29: TPASS: Expect: parent ID (14048) differs from
> thread[2] ID (14051)
>         gettid02.c:29: TPASS: Expect: parent ID (14048) differs from
> thread[3] ID (14052)
>         gettid02.c:29: TPASS: Expect: parent ID (14048) differs from
> thread[4] ID (14053)
>         gettid02.c:29: TPASS: Expect: parent ID (14048) differs from
> thread[5] ID (14054)
>         gettid02.c:29: TPASS: Expect: parent ID (14048) differs from
> thread[6] ID (14055)
>         gettid02.c:29: TPASS: Expect: parent ID (14048) differs from
> thread[7] ID (14056)
>         gettid02.c:29: TPASS: Expect: parent ID (14048) differs from
> thread[8] ID (14057)
>         gettid02.c:29: TPASS: Expect: parent ID (14048) differs from
> thread[9] ID (14058)
>         gettid02.c:49: TINFO: thread[0] and thread[1] have the same ID
>         gettid02.c:49: TINFO: thread[0] and thread[2] have the same ID
>         gettid02.c:49: TINFO: thread[0] and thread[3] have the same ID
>         ...
> which is clearly wrong, since each thread above printed different ID.
>
> This construct is race-y on slower s390x systems:
>         for (int i = 0; i < THREADS_NUM; i++)
>                 SAFE_PTHREAD_CREATE(&thread, NULL, threaded, &i);
> because by the time thread starts and looks at "&i", the loop can
> already move on and increment "i".
>

Sorry, just come up one more question, pthread_join will stay there
until the thread revokes finish, so why the loop can move on and increase i?



>
> Also, potentially starting and waiting for each thread could be an issue,
> since kernel is
> free to re-use tid for already finished threads.
>
> Instead of passing tid via pthread_join, just use already available global
> array "tids".
> Make sure the argument to pthread_create doesn't change, by creating an
> args array.
> Start all threads before we join any.
> And also print the value of TID in cases where test detects two threads
> use same one.
>
> Signed-off-by: Jan Stancek <jstancek@redhat.com>
> ---
>  testcases/kernel/syscalls/gettid/gettid02.c | 17 ++++++++++-------
>  1 file changed, 10 insertions(+), 7 deletions(-)
>
> diff --git a/testcases/kernel/syscalls/gettid/gettid02.c
> b/testcases/kernel/syscalls/gettid/gettid02.c
> index 61f115fc9e7c..ef44761c41de 100644
> --- a/testcases/kernel/syscalls/gettid/gettid02.c
> +++ b/testcases/kernel/syscalls/gettid/gettid02.c
> @@ -16,7 +16,7 @@
>
>  #define THREADS_NUM 10
>
> -static pid_t tids[THREADS_NUM];
> +static volatile pid_t tids[THREADS_NUM];
>
>  static void *threaded(void *arg)
>  {
> @@ -29,24 +29,27 @@ static void *threaded(void *arg)
>         TST_EXP_EXPR(pid != tid,
>                 "parent ID (%d) differs from thread[%d] ID (%d)",
>                 pid, i, tid);
> -
> -       return (void *)tst_syscall(__NR_gettid);
> +       tids[i] = tid;
> +       return NULL;
>  }
>
>  static void run(void)
>  {
> -       pthread_t thread;
> +       pthread_t thread[THREADS_NUM];
> +       int args[THREADS_NUM];
>         int error = 0;
>
>         for (int i = 0; i < THREADS_NUM; i++) {
> -               SAFE_PTHREAD_CREATE(&thread, NULL, threaded, &i);
> -               SAFE_PTHREAD_JOIN(thread, (void **)&tids[i]);
> +               args[i] = i;
> +               SAFE_PTHREAD_CREATE(&thread[i], NULL, threaded, &args[i]);
>         }
> +       for (int i = 0; i < THREADS_NUM; i++)
> +               SAFE_PTHREAD_JOIN(thread[i], NULL);
>
>         for (int i = 0; i < THREADS_NUM; i++) {
>                 for (int j = i + 1; j < THREADS_NUM; j++) {
>                         if (tids[i] == tids[j]) {
> -                               tst_res(TINFO, "thread[%d] and thread[%d]
> have the same ID", i, j);
> +                               tst_res(TINFO, "thread[%d] and thread[%d]
> have the same ID %d", i, j, tids[i]);
>                                 error = 1;
>                         }
>                 }
> --
> 2.31.1
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
>
>

-- 
Regards,
Li Wang


More information about the ltp mailing list