[dpdk-dev,v2] eal: fix compile error for old glibc caused by pthread_setname_np()

Message ID 1448450035-23991-1-git-send-email-ferruh.yigit@intel.com (mailing list archive)
State Accepted, archived
Headers

Commit Message

Ferruh Yigit Nov. 25, 2015, 11:13 a.m. UTC
  Fixes: 67b6d3039e9e ("eal: set name to threads")

pthread_setname_np() function added in glibc 2.12, using this function
in older glibc versions cause compile error:
error: implicit declaration of function "pthread_setname_np"

This patch adds "rte_thread_setname" macro and set it according
glibc >= 2.12 check, thread naming disabled for older glibc versions,
glibc versions that support "pthread_setname_np" will keep using this
function.

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 examples/tep_termination/main.c                    |  2 +-
 examples/vhost/main.c                              |  2 +-
 examples/vhost_xen/main.c                          |  2 +-
 lib/librte_eal/common/include/rte_lcore.h          | 20 ++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal.c                  |  2 +-
 lib/librte_eal/linuxapp/eal/eal_interrupts.c       |  2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio_mp_sync.c |  2 +-
 lib/librte_eal/linuxapp/eal/eal_timer.c            |  2 +-
 8 files changed, 27 insertions(+), 7 deletions(-)
  

Comments

Thomas Monjalon Nov. 25, 2015, 11:18 a.m. UTC | #1
2015-11-25 11:13, Ferruh Yigit:
> +/**
> + * Set thread names.
> + *
> + * Macro to wrap `pthread_setname_np()` with a glibc version check.
> + * Only glibc >= 2.12 supports this feature.
> + *
> + * This macro only used for Linux, BSD does direct libc call.
> + * BSD libc version of function is `pthread_set_name_np()`.
> + */
> +#if defined(__DOXYGEN__)
> +#define rte_thread_setname(...) pthread_setname_np(__VA_ARGS__)
> +#endif
> +
> +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
> +#if __GLIBC_PREREQ(2, 12)
> +#define rte_thread_setname(...) pthread_setname_np(__VA_ARGS__)
> +#else
> +#define rte_thread_setname(...) 0
> +#endif
> +#endif

OK it is a first (and important) fix.
EAL is an abstraction for Linux and FreeBSD, so ideally another patch would
make rte_thread_setname working for BSD too.
  
Thomas Monjalon Nov. 25, 2015, 11:30 a.m. UTC | #2
2015-11-25 11:24, Ferruh Yigit:
> On Wed, Nov 25, 2015 at 12:18:02PM +0100, Thomas Monjalon wrote:
> > 2015-11-25 11:13, Ferruh Yigit:
> > > +/**
> > > + * Set thread names.
> > > + *
> > > + * Macro to wrap `pthread_setname_np()` with a glibc version check.
> > > + * Only glibc >= 2.12 supports this feature.
> > > + *
> > > + * This macro only used for Linux, BSD does direct libc call.
> > > + * BSD libc version of function is `pthread_set_name_np()`.
> > > + */
> > > +#if defined(__DOXYGEN__)
> > > +#define rte_thread_setname(...) pthread_setname_np(__VA_ARGS__)
> > > +#endif
> > > +
> > > +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
> > > +#if __GLIBC_PREREQ(2, 12)
> > > +#define rte_thread_setname(...) pthread_setname_np(__VA_ARGS__)
> > > +#else
> > > +#define rte_thread_setname(...) 0
> > > +#endif
> > > +#endif
> > 
> > OK it is a first (and important) fix.
> > EAL is an abstraction for Linux and FreeBSD, so ideally another patch would
> > make rte_thread_setname working for BSD too.
> 
> I wasn't sure to do that update, since BSD has nothing with glibc versions.
> Do you want me amend this patch to update BSD usage to rte_thread_setname?

No, for 2.2, you have fixed the glibc issue, that's enough.
BSD support can be another path as it is not a real issue currently.
  
Thomas Monjalon Nov. 25, 2015, 1:41 p.m. UTC | #3
2015-11-25 11:13, Ferruh Yigit:
> Fixes: 67b6d3039e9e ("eal: set name to threads")
> 
> pthread_setname_np() function added in glibc 2.12, using this function
> in older glibc versions cause compile error:
> error: implicit declaration of function "pthread_setname_np"
> 
> This patch adds "rte_thread_setname" macro and set it according
> glibc >= 2.12 check, thread naming disabled for older glibc versions,
> glibc versions that support "pthread_setname_np" will keep using this
> function.
> 
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>

Applied as eal/linux fix, thanks
  
Roger Melton Nov. 25, 2015, 1:51 p.m. UTC | #4
> +/**
> + * Set thread names.
> + *
> + * Macro to wrap `pthread_setname_np()` with a glibc version check.
> + * Only glibc >= 2.12 supports this feature.
> + *
> + * This macro only used for Linux, BSD does direct libc call.
> + * BSD libc version of function is `pthread_set_name_np()`.
> + */
> +#if defined(__DOXYGEN__)
> +#define rte_thread_setname(...) pthread_setname_np(__VA_ARGS__)
> +#endif
> +
> +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
> +#if __GLIBC_PREREQ(2, 12)
> +#define rte_thread_setname(...) pthread_setname_np(__VA_ARGS__)
> +#else
> +#define rte_thread_setname(...) 0
> +#endif
> +#endif

Have you thought about a way to set thread name when glibc < 2.12.  I 
also ran into the problem recently and played around with prctl() 
(Linux) to set thread (process) name.  e.g.

    ret = prctl(PR_SET_NAME,<thread_name>,0,0,0);


There are 2 issues I think:

    1) The semantics are different than prthread_setname_np().  With
    pthread_setname_np() a name can be assigned to any thread, with
    prctl() the name is assigned to the active thread.  That would mean
    that rather than rte_eal_init(), rte_eal_intr_init() could not
    assign thread names.  Rather the threads would have to name themselves.

    2) I think BSD lacks prctl(), but some (not all?) BSD
    implementations have setproctitle() to do the same thing.


It might be too late for 2.2, but something to think about for the future.

Regards,
Roger
  
Thomas Monjalon Nov. 25, 2015, 2:03 p.m. UTC | #5
2015-11-25 08:51, Roger B. Melton:
> Have you thought about a way to set thread name when glibc < 2.12.  I 
> also ran into the problem recently and played around with prctl() 
> (Linux) to set thread (process) name.  e.g.
> 
>     ret = prctl(PR_SET_NAME,<thread_name>,0,0,0);
> 
> 
> There are 2 issues I think:
> 
>     1) The semantics are different than prthread_setname_np().  With
>     pthread_setname_np() a name can be assigned to any thread, with
>     prctl() the name is assigned to the active thread.  That would mean
>     that rather than rte_eal_init(), rte_eal_intr_init() could not
>     assign thread names.  Rather the threads would have to name themselves.
> 
>     2) I think BSD lacks prctl(), but some (not all?) BSD
>     implementations have setproctitle() to do the same thing.
> 
> 
> It might be too late for 2.2, but something to think about for the future.

I don't think this feature is important enough to deal with old environments
and to risk some complicated bugs.
Do you think it deserves more tricks?
  
Roger Melton Nov. 25, 2015, 2:20 p.m. UTC | #6
On 11/25/15 9:03 AM, Thomas Monjalon wrote:
> 2015-11-25 08:51, Roger B. Melton:
>> Have you thought about a way to set thread name when glibc < 2.12.  I
>> also ran into the problem recently and played around with prctl()
>> (Linux) to set thread (process) name.  e.g.
>>
>>      ret = prctl(PR_SET_NAME,<thread_name>,0,0,0);
>>
>>
>> There are 2 issues I think:
>>
>>      1) The semantics are different than prthread_setname_np().  With
>>      pthread_setname_np() a name can be assigned to any thread, with
>>      prctl() the name is assigned to the active thread.  That would mean
>>      that rather than rte_eal_init(), rte_eal_intr_init() could not
>>      assign thread names.  Rather the threads would have to name themselves.
>>
>>      2) I think BSD lacks prctl(), but some (not all?) BSD
>>      implementations have setproctitle() to do the same thing.
>>
>>
>> It might be too late for 2.2, but something to think about for the future.
> I don't think this feature is important enough to deal with old environments
> and to risk some complicated bugs.
> Do you think it deserves more tricks?
> .
>
I agree with you Thomas.  While I am one of those living in an old 
environment, I believe that the complications of the tricks out weight 
the debug benefit.  However there may be other in the community who have 
a different view, so I thought I would at least suggest that there are 
alternatives.

Thanks,
-Roger
  

Patch

diff --git a/examples/tep_termination/main.c b/examples/tep_termination/main.c
index 2b67e64..f97d552 100644
--- a/examples/tep_termination/main.c
+++ b/examples/tep_termination/main.c
@@ -1249,7 +1249,7 @@  main(int argc, char *argv[])
 		if (ret != 0)
 			rte_exit(EXIT_FAILURE, "Cannot create print-stats thread\n");
 		snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "print-stats");
-		ret = pthread_setname_np(tid, thread_name);
+		ret = rte_thread_setname(tid, thread_name);
 		if (ret != 0)
 			RTE_LOG(ERR, VHOST_CONFIG, "Cannot set print-stats name\n");
 	}
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index c081b18..9bfda6d 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -3027,7 +3027,7 @@  main(int argc, char *argv[])
 
 		/* Set thread_name for aid in debugging.  */
 		snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "print-stats");
-		ret = pthread_setname_np(tid, thread_name);
+		ret = rte_thread_setname(tid, thread_name);
 		if (ret != 0)
 			RTE_LOG(ERR, VHOST_CONFIG,
 				"Cannot set print-stats name\n");
diff --git a/examples/vhost_xen/main.c b/examples/vhost_xen/main.c
index 3fcc138..ca725f2 100644
--- a/examples/vhost_xen/main.c
+++ b/examples/vhost_xen/main.c
@@ -1510,7 +1510,7 @@  main(int argc, char *argv[])
 
 		/* Set thread_name for aid in debugging. */
 		snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "print-xen-stats");
-		ret = pthread_setname_np(tid, thread_name);
+		ret = rte_thread_setname(tid, thread_name);
 		if (ret != 0)
 			RTE_LOG(ERR, VHOST_CONFIG,
 				"Cannot set print-stats name\n");
diff --git a/lib/librte_eal/common/include/rte_lcore.h b/lib/librte_eal/common/include/rte_lcore.h
index e03264e..25460b9 100644
--- a/lib/librte_eal/common/include/rte_lcore.h
+++ b/lib/librte_eal/common/include/rte_lcore.h
@@ -247,6 +247,26 @@  int rte_thread_set_affinity(rte_cpuset_t *cpusetp);
  */
 void rte_thread_get_affinity(rte_cpuset_t *cpusetp);
 
+/**
+ * Set thread names.
+ *
+ * Macro to wrap `pthread_setname_np()` with a glibc version check.
+ * Only glibc >= 2.12 supports this feature.
+ *
+ * This macro only used for Linux, BSD does direct libc call.
+ * BSD libc version of function is `pthread_set_name_np()`.
+ */
+#if defined(__DOXYGEN__)
+#define rte_thread_setname(...) pthread_setname_np(__VA_ARGS__)
+#endif
+
+#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
+#if __GLIBC_PREREQ(2, 12)
+#define rte_thread_setname(...) pthread_setname_np(__VA_ARGS__)
+#else
+#define rte_thread_setname(...) 0
+#endif
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 06536f2..635ec36 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -859,7 +859,7 @@  rte_eal_init(int argc, char **argv)
 		/* Set thread_name for aid in debugging. */
 		snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN,
 			"lcore-slave-%d", i);
-		ret = pthread_setname_np(lcore_config[i].thread_id,
+		ret = rte_thread_setname(lcore_config[i].thread_id,
 						thread_name);
 		if (ret != 0)
 			RTE_LOG(ERR, EAL,
diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
index 95beb4c..470d6a1 100644
--- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
@@ -887,7 +887,7 @@  rte_eal_intr_init(void)
 		/* Set thread_name for aid in debugging. */
 		snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN,
 			"eal-intr-thread");
-		ret_1 = pthread_setname_np(intr_thread, thread_name);
+		ret_1 = rte_thread_setname(intr_thread, thread_name);
 		if (ret_1 != 0)
 			RTE_LOG(ERR, EAL,
 			"Failed to set thread name for interrupt handling\n");
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio_mp_sync.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio_mp_sync.c
index 277565d..d9188fd 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio_mp_sync.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio_mp_sync.c
@@ -394,7 +394,7 @@  pci_vfio_mp_sync_setup(void)
 
 	/* Set thread_name for aid in debugging. */
 	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "pci-vfio-sync");
-	ret = pthread_setname_np(socket_thread, thread_name);
+	ret = rte_thread_setname(socket_thread, thread_name);
 	if (ret)
 		RTE_LOG(ERR, EAL,
 			"Failed to set thread name for secondary processes!\n");
diff --git a/lib/librte_eal/linuxapp/eal/eal_timer.c b/lib/librte_eal/linuxapp/eal/eal_timer.c
index e0642de..9ceff33 100644
--- a/lib/librte_eal/linuxapp/eal/eal_timer.c
+++ b/lib/librte_eal/linuxapp/eal/eal_timer.c
@@ -219,7 +219,7 @@  rte_eal_hpet_init(int make_default)
 	 * Set thread_name for aid in debugging.
 	 */
 	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "hpet-msb-inc");
-	ret = pthread_setname_np(msb_inc_thread_id, thread_name);
+	ret = rte_thread_setname(msb_inc_thread_id, thread_name);
 	if (ret != 0)
 		RTE_LOG(ERR, EAL,
 			"ERROR: Cannot set HPET timer thread name!\n");