eal: fix threads block on barrier
authorJianfeng Tan <jianfeng.tan@intel.com>
Fri, 27 Apr 2018 16:41:42 +0000 (16:41 +0000)
committerThomas Monjalon <thomas@monjalon.net>
Fri, 27 Apr 2018 19:47:43 +0000 (21:47 +0200)
Below commit introduced pthread barrier for synchronization.
But two IPC threads block on the barrier, and never wake up.

  (gdb) bt
  #0  futex_wait (private=0, expected=0, futex_word=0x7fffffffcff4)
      at ../sysdeps/unix/sysv/linux/futex-internal.h:61
  #1  futex_wait_simple (private=0, expected=0, futex_word=0x7fffffffcff4)
      at ../sysdeps/nptl/futex-internal.h:135
  #2  __pthread_barrier_wait (barrier=0x7fffffffcff0) at pthread_barrier_wait.c:184
  #3  rte_thread_init (arg=0x7fffffffcfe0)
      at ../dpdk/lib/librte_eal/common/eal_common_thread.c:160
  #4  start_thread (arg=0x7ffff6ecf700) at pthread_create.c:333
  #5  clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Through analysis, we find the barrier defined on the stack could be the
root cause. This patch will change to use heap memory as the barrier.

Fixes: d651ee4919cd ("eal: set affinity for control threads")

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
lib/librte_eal/common/eal_common_thread.c

index fcf00cd..de69452 100644 (file)
@@ -163,17 +163,21 @@ rte_ctrl_thread_create(pthread_t *thread, const char *name,
                const pthread_attr_t *attr,
                void *(*start_routine)(void *), void *arg)
 {
-       struct rte_thread_ctrl_params params = {
-               .start_routine = start_routine,
-               .arg = arg,
-       };
+       struct rte_thread_ctrl_params *params;
        unsigned int lcore_id;
        rte_cpuset_t cpuset;
        int cpu_found, ret;
 
-       pthread_barrier_init(&params.configured, NULL, 2);
+       params = malloc(sizeof(*params));
+       if (!params)
+               return -1;
+
+       params->start_routine = start_routine;
+       params->arg = arg;
 
-       ret = pthread_create(thread, attr, rte_thread_init, (void *)&params);
+       pthread_barrier_init(&params->configured, NULL, 2);
+
+       ret = pthread_create(thread, attr, rte_thread_init, (void *)params);
        if (ret != 0)
                return ret;
 
@@ -200,12 +204,14 @@ rte_ctrl_thread_create(pthread_t *thread, const char *name,
        if (ret < 0)
                goto fail;
 
-       pthread_barrier_wait(&params.configured);
+       pthread_barrier_wait(&params->configured);
+       free(params);
 
        return 0;
 
 fail:
        pthread_cancel(*thread);
        pthread_join(*thread, NULL);
+       free(params);
        return ret;
 }