Skip to contentSkip to conversation

perf tools: Work around lack of sched_getcpu in glibc < 2.6.

PATCH Superseded Vinson Lee 7 participants 15 messages Feb 14, 2015 – Mar 24, 2015 perf events

lore
Share & tools
lore

Vinson Lee

author
#0 lore raw

PATCH 1/1 perf tools: Work around lack of sched_getcpu in glibc < 2.6.

From: Vinson Lee <[email protected]>

This patch fixes this build error with glibc < 2.6.

CC util/cloexec.o
cc1: warnings being treated as errors
util/cloexec.c: In function ‘perf_flag_probe’:
util/cloexec.c:24: error: implicit declaration of function ‘sched_getcpu’
util/cloexec.c:24: error: nested extern declaration of ‘sched_getcpu’
make: *** [util/cloexec.o] Error 1

---
 tools/perf/util/cloexec.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
tools/perf/util/cloexec.c +10 -0
index 47b78b3..3738924 100644
@@ -7,6 +7,12 @@
 
 static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
 
+#ifdef __GLIBC_PREREQ
+#if __GLIBC_PREREQ(2, 6)
+#define HAVE_SCHED_GETCPU
+#endif
+#endif
+
 static int perf_flag_probe(void)
 {
 	/* use 'safest' configuration as used in perf_evsel__fallback() */
@@ -21,9 +27,13 @@ static int perf_flag_probe(void)
 	pid_t pid = -1;
 	char sbuf[STRERR_BUFSIZE];
 
+#ifdef HAVE_SCHED_GETCPU
 	cpu = sched_getcpu();
 	if (cpu < 0)
 		cpu = 0;
+#else
+	cpu = 0;
+#endif
 
 	while (1) {
 		/* check cloexec flag */
Signature · 1 line
1.8.2.1
Reviewed-by on v1 1/1
#1 lore raw

Hi,

Quoted 23 lines · Vinson Lee

From: Vinson Lee <[email protected]>

This patch fixes this build error with glibc < 2.6.

CC util/cloexec.o
cc1: warnings being treated as errors
util/cloexec.c: In function ‘perf_flag_probe’:
util/cloexec.c:24: error: implicit declaration of function ‘sched_getcpu’
util/cloexec.c:24: error: nested extern declaration of ‘sched_getcpu’
make: *** [util/cloexec.o] Error 1

---
 tools/perf/util/cloexec.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
tools/perf/util/cloexec.c +0 -0
index 47b78b3..3738924 100644

tools/perf/util/cloexec.c line 15

Quoted 9 lines
tools/perf/util/cloexec.c +6 -0
@@ -7,6 +7,12 @@
 
 static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
 
+#ifdef __GLIBC_PREREQ
+#if __GLIBC_PREREQ(2, 6)
+#define HAVE_SCHED_GETCPU
+#endif
+#endif
+

OK

Quoted 7 lines
tools/perf/util/cloexec.c +0 -0
 static int perf_flag_probe(void)
 {
 	/* use 'safest' configuration as used in perf_evsel__fallback() */
@@ -21,9 +27,13 @@ static int perf_flag_probe(void)
 	pid_t pid = -1;
 	char sbuf[STRERR_BUFSIZE];
 

tools/perf/util/cloexec.c static int perf_flag_probe(void) · line 39

Quoted 10 lines
tools/perf/util/cloexec.c +4 -0
+#ifdef HAVE_SCHED_GETCPU
 	cpu = sched_getcpu();
 	if (cpu < 0)
 		cpu = 0;
+#else
+	cpu = 0;
+#endif
 
 	while (1) {
 		/* check cloexec flag */

I've reviewed the use of __GLIBC_PREREQ(2, 6), but not whether using cpu = 0 is OK if sched_getcpu() is not available.

Regards.

Signature · 2 lines
Yann Droneaud
OPTEYA
author
#2 lore raw
Quoted 59 lines · Yann Droneaud

Hi,

Quoted 23 lines · Vinson Lee

From: Vinson Lee <[email protected]>

This patch fixes this build error with glibc < 2.6.

CC util/cloexec.o
cc1: warnings being treated as errors
util/cloexec.c: In function ‘perf_flag_probe’:
util/cloexec.c:24: error: implicit declaration of function ‘sched_getcpu’
util/cloexec.c:24: error: nested extern declaration of ‘sched_getcpu’
make: *** [util/cloexec.o] Error 1

---
 tools/perf/util/cloexec.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
tools/perf/util/cloexec.c +0 -0
index 47b78b3..3738924 100644

tools/perf/util/cloexec.c line 15

Quoted 9 lines
tools/perf/util/cloexec.c +6 -0
@@ -7,6 +7,12 @@
 
 static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
 
+#ifdef __GLIBC_PREREQ
+#if __GLIBC_PREREQ(2, 6)
+#define HAVE_SCHED_GETCPU
+#endif
+#endif
+

OK

Quoted 7 lines
tools/perf/util/cloexec.c +0 -0
 static int perf_flag_probe(void)
 {
      /* use 'safest' configuration as used in perf_evsel__fallback() */
@@ -21,9 +27,13 @@ static int perf_flag_probe(void)
      pid_t pid = -1;
      char sbuf[STRERR_BUFSIZE];
 

tools/perf/util/cloexec.c static int perf_flag_probe(void) · line 39

Quoted 10 lines
tools/perf/util/cloexec.c +4 -0
+#ifdef HAVE_SCHED_GETCPU
      cpu = sched_getcpu();
      if (cpu < 0)
              cpu = 0;
+#else
+     cpu = 0;
+#endif
 
      while (1) {
              /* check cloexec flag */

I've reviewed the use of __GLIBC_PREREQ(2, 6), but not whether using cpu = 0 is OK if sched_getcpu() is not available.

Quoted 10 lines

Regards.

--
Yann Droneaud
OPTEYA

Ping. Please review the sched_getcpu hunk.

maintainer
#3 lore raw
Quoted 19 lines · Vinson Lee
Quoted 18 lines · Yann Droneaud
Quoted 18 lines
tools/perf/util/cloexec.c +9 -0
+#ifdef __GLIBC_PREREQ
+#if __GLIBC_PREREQ(2, 6)
+#define HAVE_SCHED_GETCPU
+#endif
+#endif
@@ -21,9 +27,13 @@ static int perf_flag_probe(void)
      pid_t pid = -1;
      char sbuf[STRERR_BUFSIZE];
 
+#ifdef HAVE_SCHED_GETCPU
      cpu = sched_getcpu();
      if (cpu < 0)
              cpu = 0;
+#else
+     cpu = 0;
+#endif
 
Quoted 2 lines
Quoted 2 lines

tools/perf/util/cloexec.c static int perf_flag_probe(void) · line 39

Quoted 2 lines
tools/perf/util/cloexec.c +0 -0
      while (1) {
              /* check cloexec flag */

Would it not be much nicer to implement a sched_getcpu() stub that returns -1 and sets errno to -ENOSYS or something?

That avoids the magic #ifdef mushroom.

author
#4 lore raw

PATCH v2 1/1 perf tools: Work around lack of sched_getcpu in glibc < 2.6.

From: Vinson Lee <[email protected]>

This patch fixes this build error with glibc < 2.6.

CC util/cloexec.o
cc1: warnings being treated as errors
util/cloexec.c: In function ‘perf_flag_probe’:
util/cloexec.c:24: error: implicit declaration of function ‘sched_getcpu’
util/cloexec.c:24: error: nested extern declaration of ‘sched_getcpu’
make: *** [util/cloexec.o] Error 1

---
 tools/perf/util/cloexec.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
tools/perf/util/cloexec.c +10 -0
index 6da965b..285bd70 100644
@@ -7,6 +7,16 @@
 
 static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
 
+#ifdef __GLIBC_PREREQ
+#if !__GLIBC_PREREQ(2, 6)
+static int sched_getcpu(void)
+{
+	errno = ENOSYS;
+	return -1;
+}
+#endif
+#endif
+
 static int perf_flag_probe(void)
 {
 	/* use 'safest' configuration as used in perf_evsel__fallback() */
Signature · 1 line
1.8.2.1
#5 lore raw
Quoted 25 lines · Vinson Lee

From: Vinson Lee <[email protected]>

This patch fixes this build error with glibc < 2.6.

CC util/cloexec.o
cc1: warnings being treated as errors
util/cloexec.c: In function ‘perf_flag_probe’:
util/cloexec.c:24: error: implicit declaration of function ‘sched_getcpu’
util/cloexec.c:24: error: nested extern declaration of ‘sched_getcpu’
make: *** [util/cloexec.o] Error 1

---
 tools/perf/util/cloexec.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
tools/perf/util/cloexec.c +0 -0
index 6da965b..285bd70 100644
@@ -7,6 +7,16 @@
 
 static unsigned long flag = PERF_FLAG_FD_CLOEXEC;

tools/perf/util/cloexec.c line 18

Quoted 10 lines
tools/perf/util/cloexec.c +9 -0
 
+#ifdef __GLIBC_PREREQ
+#if !__GLIBC_PREREQ(2, 6)
+static int sched_getcpu(void)
+{
+	errno = ENOSYS;
+	return -1;
+}
+#endif
+#endif

you could mark it as __weak and get rid of those ifdef's like we do for strlcpy in utilpath.c

jirka

#6 lore raw

Em Thu, Mar 19, 2015 at 11:13:04AM +0100, Jiri Olsa escreveu:

Quoted 15 lines · Vinson Lee

tools/perf/util/cloexec.c line 18

Quoted 11 lines

This patch fixes this build error with glibc < 2.6.

tools/perf/util/cloexec.c +9 -0
+#ifdef __GLIBC_PREREQ
+#if !__GLIBC_PREREQ(2, 6)
+static int sched_getcpu(void)
+{
+	errno = ENOSYS;
+	return -1;
+}
+#endif
+#endif

you could mark it as __weak and get rid of those ifdef's like we do for strlcpy in utilpath.c

Agreed.

- Arnaldo

author
#7 lore raw
Quoted 17 lines · Arnaldo Carvalho de Melo

Em Thu, Mar 19, 2015 at 11:13:04AM +0100, Jiri Olsa escreveu:

Quoted 15 lines · Vinson Lee

tools/perf/util/cloexec.c line 18

Quoted 11 lines

This patch fixes this build error with glibc < 2.6.

tools/perf/util/cloexec.c +9 -0
+#ifdef __GLIBC_PREREQ
+#if !__GLIBC_PREREQ(2, 6)
+static int sched_getcpu(void)
+{
+   errno = ENOSYS;
+   return -1;
+}
+#endif
+#endif

you could mark it as __weak and get rid of those ifdef's like we do for strlcpy in utilpath.c

Quoted 3 lines

Agreed.

- Arnaldo

I tried this approach but am having trouble getting a patch to compile with both older glibc and recent glibc.

With older glibc I will get a "no previous prototype" compilation error. I can fix this error by adding a prototype but this results in a "redundant redeclaration" error with newer glibc.

#8 lore raw

Em Thu, Mar 19, 2015 at 02:12:05PM -0700, Vinson Lee escreveu:

Quoted 19 lines
Quoted 17 lines · Arnaldo Carvalho de Melo

Em Thu, Mar 19, 2015 at 11:13:04AM +0100, Jiri Olsa escreveu:

Quoted 15 lines · Vinson Lee

tools/perf/util/cloexec.c line 18

Quoted 11 lines

This patch fixes this build error with glibc < 2.6.

tools/perf/util/cloexec.c +9 -0
+#ifdef __GLIBC_PREREQ
+#if !__GLIBC_PREREQ(2, 6)
+static int sched_getcpu(void)
+{
+   errno = ENOSYS;
+   return -1;
+}
+#endif
+#endif

you could mark it as __weak and get rid of those ifdef's like we do for strlcpy in utilpath.c

Quoted 8 lines
Quoted 1 line

Agreed.

I tried this approach but am having trouble getting a patch to compile with both older glibc and recent glibc.

With older glibc I will get a "no previous prototype" compilation error. I can fix this error by adding a prototype but this results in a "redundant redeclaration" error with newer glibc.

So for strlcpy we have in tools/perf/util/cache.h:

#ifndef __UCLIBC__
/* Matches the libc/libbsd function attribute so we declare this
* unconditionally: */
extern size_t strlcpy(char *dest, const char *src, size_t size); #endif

I.e. have the ifdef just in the header file.

This way, if we end up needing to use sched_getcpu elsewhere, it will work and the needed #ifdef will be constrained to the header file.

At some point we should try to move these functions to some libc-compat.c file and move it to somewhere in tools/lib/.

- Arnaldo

author
#9 lore raw
Quoted 39 lines · Arnaldo Carvalho de Melo

Em Thu, Mar 19, 2015 at 02:12:05PM -0700, Vinson Lee escreveu:

Quoted 19 lines
Quoted 17 lines · Arnaldo Carvalho de Melo

Em Thu, Mar 19, 2015 at 11:13:04AM +0100, Jiri Olsa escreveu:

Quoted 15 lines · Vinson Lee

Review

Quoted 11 lines

This patch fixes this build error with glibc < 2.6.

(quoted diff) +9 -0
+#ifdef __GLIBC_PREREQ
+#if !__GLIBC_PREREQ(2, 6)
+static int sched_getcpu(void)
+{
+   errno = ENOSYS;
+   return -1;
+}
+#endif
+#endif

you could mark it as __weak and get rid of those ifdef's like we do for strlcpy in utilpath.c

Quoted 8 lines
Quoted 1 line

Agreed.

I tried this approach but am having trouble getting a patch to compile with both older glibc and recent glibc.

With older glibc I will get a "no previous prototype" compilation error. I can fix this error by adding a prototype but this results in a "redundant redeclaration" error with newer glibc.

So for strlcpy we have in tools/perf/util/cache.h:

#ifndef __UCLIBC__
/* Matches the libc/libbsd function attribute so we declare this
* unconditionally: */
extern size_t strlcpy(char *dest, const char *src, size_t size); #endif

I.e. have the ifdef just in the header file.

Quoted 7 lines

This way, if we end up needing to use sched_getcpu elsewhere, it will work and the needed #ifdef will be constrained to the header file.

At some point we should try to move these functions to some libc-compat.c file and move it to somewhere in tools/lib/.

- Arnaldo

I tried moving the prototype to a header file and it does not compile with newer glibc for me either. I still get a "redundant redeclaration" compiler error.

Here is the diff that I tried.

tools/perf/util/cloexec.c +6 -0
index 6da965b..85b5238 100644
@@ -7,6 +7,12 @@
 
 static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
 
+int __weak sched_getcpu(void)
+{
+       errno = ENOSYS;
+       return -1;
+}
+
 static int perf_flag_probe(void)
 {
        /* use 'safest' configuration as used in perf_evsel__fallback() */
tools/perf/util/cloexec.h +2 -0
index 94a5a7d..06904bc 100644
@@ -3,4 +3,6 @@
 
 unsigned long perf_event_open_cloexec_flag(void);
 
+extern int sched_getcpu(void) __THROW;
+
 #endif /* __PERF_CLOEXEC_H */
#10 lore raw

Em Fri, Mar 20, 2015 at 11:44:42AM -0700, Vinson Lee escreveu:

Quoted 10 lines · Arnaldo Carvalho de Melo
Quoted 9 lines

So for strlcpy we have in tools/perf/util/cache.h:

#ifndef __UCLIBC__
/* Matches the libc/libbsd function attribute so we declare this
* unconditionally: */
extern size_t strlcpy(char *dest, const char *src, size_t size); #endif

I.e. have the ifdef just in the header file.

This part you didn't take into account, the __weak marked part is ok, the linker will DTRT with that, its just the redeclaration part that needs to get out of the way, enclose that under appropriate ifdef, i.e. one that is associated with the libc where that file first appeared and that has been present since then.

- Arnaldo

Quoted 31 lines
Quoted 2 lines

This way, if we end up needing to use sched_getcpu elsewhere, it will work and the needed #ifdef will be constrained to the header file.

I tried moving the prototype to a header file and it does not compile with newer glibc for me either. I still get a "redundant redeclaration" compiler error.

Here is the diff that I tried.

tools/perf/util/cloexec.c +6 -0
@@ -7,6 +7,12 @@
 
 static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
 
+int __weak sched_getcpu(void)
+{
+       errno = ENOSYS;
+       return -1;
+}
+
 static int perf_flag_probe(void)
 {
        /* use 'safest' configuration as used in perf_evsel__fallback() */
tools/perf/util/cloexec.h +2 -0
@@ -3,4 +3,6 @@
 
 unsigned long perf_event_open_cloexec_flag(void);
 
+extern int sched_getcpu(void) __THROW;
+
 #endif /* __PERF_CLOEXEC_H */
author
#11 lore raw

PATCH v3 1/1 perf tools: Work around lack of sched_getcpu in glibc < 2.6.

From: Vinson Lee <[email protected]>

This patch fixes this build error with glibc < 2.6.

CC util/cloexec.o
cc1: warnings being treated as errors
util/cloexec.c: In function ‘perf_flag_probe’:
util/cloexec.c:24: error: implicit declaration of function ‘sched_getcpu’
util/cloexec.c:24: error: nested extern declaration of ‘sched_getcpu’
make: *** [util/cloexec.o] Error 1

---
 tools/perf/util/cloexec.c | 6 ++++++
 tools/perf/util/cloexec.h | 6 ++++++
 2 files changed, 12 insertions(+)
tools/perf/util/cloexec.c +6 -0
index 6da965b..85b5238 100644
@@ -7,6 +7,12 @@
 
 static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
 
+int __weak sched_getcpu(void)
+{
+	errno = ENOSYS;
+	return -1;
+}
+
 static int perf_flag_probe(void)
 {
 	/* use 'safest' configuration as used in perf_evsel__fallback() */
tools/perf/util/cloexec.h +6 -0
index 94a5a7d..68888c2 100644
@@ -3,4 +3,10 @@
 
 unsigned long perf_event_open_cloexec_flag(void);
 
+#ifdef __GLIBC_PREREQ
+#if !__GLIBC_PREREQ(2, 6)
+extern int sched_getcpu(void) __THROW;
+#endif
+#endif
+
 #endif /* __PERF_CLOEXEC_H */
Signature · 1 line
1.8.2.1
maintainer Acked-by on v3 1/1
#12 lore raw

Hi Vinson,

Quoted 12 lines · Vinson Lee

From: Vinson Lee <[email protected]>

This patch fixes this build error with glibc < 2.6.

CC util/cloexec.o
cc1: warnings being treated as errors
util/cloexec.c: In function ‘perf_flag_probe’:
util/cloexec.c:24: error: implicit declaration of function ‘sched_getcpu’
util/cloexec.c:24: error: nested extern declaration of ‘sched_getcpu’
make: *** [util/cloexec.o] Error 1

Quoted 2 lines

Thanks,
Namhyung

Quoted 45 lines
---
 tools/perf/util/cloexec.c | 6 ++++++
 tools/perf/util/cloexec.h | 6 ++++++
 2 files changed, 12 insertions(+)
tools/perf/util/cloexec.c +6 -0
index 6da965b..85b5238 100644
@@ -7,6 +7,12 @@
 
 static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
 
+int __weak sched_getcpu(void)
+{
+	errno = ENOSYS;
+	return -1;
+}
+
 static int perf_flag_probe(void)
 {
 	/* use 'safest' configuration as used in perf_evsel__fallback() */
tools/perf/util/cloexec.h +6 -0
index 94a5a7d..68888c2 100644
@@ -3,4 +3,10 @@
 
 unsigned long perf_event_open_cloexec_flag(void);
 
+#ifdef __GLIBC_PREREQ
+#if !__GLIBC_PREREQ(2, 6)
+extern int sched_getcpu(void) __THROW;
+#endif
+#endif
+
 #endif /* __PERF_CLOEXEC_H */
Signature · 7 lines
1.8.2.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Acked-by on v3 1/1
#13 lore raw
In reply to Vinson Lee
Quoted 12 lines · Vinson Lee

From: Vinson Lee <[email protected]>

This patch fixes this build error with glibc < 2.6.

CC util/cloexec.o
cc1: warnings being treated as errors
util/cloexec.c: In function ‘perf_flag_probe’:
util/cloexec.c:24: error: implicit declaration of function ‘sched_getcpu’
util/cloexec.c:24: error: nested extern declaration of ‘sched_getcpu’
make: *** [util/cloexec.o] Error 1

Quoted 2 lines

thanks,
jirka

Quoted 40 lines
---
 tools/perf/util/cloexec.c | 6 ++++++
 tools/perf/util/cloexec.h | 6 ++++++
 2 files changed, 12 insertions(+)
tools/perf/util/cloexec.c +6 -0
index 6da965b..85b5238 100644
@@ -7,6 +7,12 @@
 
 static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
 
+int __weak sched_getcpu(void)
+{
+	errno = ENOSYS;
+	return -1;
+}
+
 static int perf_flag_probe(void)
 {
 	/* use 'safest' configuration as used in perf_evsel__fallback() */
tools/perf/util/cloexec.h +6 -0
index 94a5a7d..68888c2 100644
@@ -3,4 +3,10 @@
 
 unsigned long perf_event_open_cloexec_flag(void);
 
+#ifdef __GLIBC_PREREQ
+#if !__GLIBC_PREREQ(2, 6)
+extern int sched_getcpu(void) __THROW;
+#endif
+#endif
+
 #endif /* __PERF_CLOEXEC_H */
Signature · 1 line
1.8.2.1
#14 lore raw
In reply to Vinson Lee
perf tools: Work around lack of sched_getcpu in glibc < 2.6.
Commit-ID:  e1e455f4f4d35850c30235747620d0d078fe9f64
Gitweb:     http://git.kernel.org/tip/e1e455f4f4d35850c30235747620d0d078fe9f64
Author:     Vinson Lee <[email protected]>
AuthorDate: Mon, 23 Mar 2015 12:09:16 -0700
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Tue, 24 Mar 2015 12:08:07 -0300

perf tools: Work around lack of sched_getcpu in glibc < 2.6.

This patch fixes this build error with glibc < 2.6.

CC util/cloexec.o
cc1: warnings being treated as errors
util/cloexec.c: In function ‘perf_flag_probe’:
util/cloexec.c:24: error: implicit declaration of function ‘sched_getcpu’
util/cloexec.c:24: error: nested extern declaration of ‘sched_getcpu’
make: *** [util/cloexec.o] Error 1

---
 tools/perf/util/cloexec.c | 6 ++++++
 tools/perf/util/cloexec.h | 6 ++++++
 2 files changed, 12 insertions(+)
tools/perf/util/cloexec.c +6 -0
index 6da965b..85b5238 100644
@@ -7,6 +7,12 @@
 
 static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
 
+int __weak sched_getcpu(void)
+{
+	errno = ENOSYS;
+	return -1;
+}
+
 static int perf_flag_probe(void)
 {
 	/* use 'safest' configuration as used in perf_evsel__fallback() */
tools/perf/util/cloexec.h +6 -0
index 94a5a7d..68888c2 100644
@@ -3,4 +3,10 @@
 
 unsigned long perf_event_open_cloexec_flag(void);
 
+#ifdef __GLIBC_PREREQ
+#if !__GLIBC_PREREQ(2, 6)
+extern int sched_getcpu(void) __THROW;
+#endif
+#endif
+
 #endif /* __PERF_CLOEXEC_H */