[dpdk-dev,v2] eal: fix compile error for old glibc caused by pthread_setname_np()
Commit Message
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
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.
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.
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
> +/**
> + * 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
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?
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
@@ -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");
}
@@ -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");
@@ -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");
@@ -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
}
@@ -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,
@@ -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");
@@ -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");
@@ -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");