since there is a need for profiling babel and other subsystems (in my
case, cake) on tiny systems, the attached patch has been sitting in my
tree for a while, and supplied here in the hope it will be useful
while its problems are sorted out...

...

openwrt: Add support for musl in the linux kernel perf utility

The linux kernel's "perf" profiling utility has a hard dependency on
glibc's strerror_r which has a notorious incompatibility with other
posix standards.

This patch wraps the musl posix std strerr_r with something that behaves like
glibc strerror_r - and currently breaks glibc support as I was unable to
figure out a combination of defines that would work mutually across both
C libraries.

My current take on it is that linux mainline perf should switch to using
strerror_l which is std and known to be thread safe, and would result in
less code....

The patch only supports linux-4.4 but is easily extended backwards.

H/T to stephen walker for the initial attempt, nbd for a refinement.

untested on anything but arm at present.
From 866299c8c0902c8e21eee7b0f54c3abd74feb494 Mon Sep 17 00:00:00 2001
From: CeroWrt Admin <[email protected]>
Date: Thu, 17 Dec 2015 12:49:36 +0100
Subject: [PATCH] openwrt: Add support for musl in the linux kernel perf
 utility

The linux kernel's "perf" profiling utility has a hard dependency on
glibc's strerror_r which is a notorious incompatability with other
posix standards.

This patch wraps the musl std strerr_r with something that behaves like
glibc strerror_r - and currently breaks glibc support as I was unable to
figure out a combination of defines that would work mutually across both
C libraries.

My current take on it is that linux mainline perf should switch to using
strerror_l which is std and known to be thread safe.

The patch only supports linux-4.4x but is easily extended backwards.

H/T to stephen walker for the initial attempt.
---
 package/devel/perf/Makefile                        |   2 +-
 .../patches-4.4/280-perf-fixes-for-musl.patch      | 143 +++++++++++++++++++++
 2 files changed, 144 insertions(+), 1 deletion(-)
 create mode 100644 target/linux/generic/patches-4.4/280-perf-fixes-for-musl.patch

diff --git a/package/devel/perf/Makefile b/package/devel/perf/Makefile
index 5e3d63f..27ef7b8 100644
--- a/package/devel/perf/Makefile
+++ b/package/devel/perf/Makefile
@@ -19,7 +19,7 @@ include $(INCLUDE_DIR)/package.mk
 define Package/perf
   SECTION:=devel
   CATEGORY:=Development
-  DEPENDS:= @USE_GLIBC +libelf1 +libdw +libpthread +librt +binutils
+  DEPENDS:=+libelf1 +libdw +libpthread +librt +binutils
   TITLE:=Linux performance monitoring tool
   VERSION:=$(LINUX_VERSION)-$(PKG_RELEASE)
   URL:=http://www.kernel.org
diff --git a/target/linux/generic/patches-4.4/280-perf-fixes-for-musl.patch b/target/linux/generic/patches-4.4/280-perf-fixes-for-musl.patch
new file mode 100644
index 0000000..029ac7d
--- /dev/null
+++ b/target/linux/generic/patches-4.4/280-perf-fixes-for-musl.patch
@@ -0,0 +1,143 @@
+From 9673ba5369408008deef840e21edab3fa7a575fd Mon Sep 17 00:00:00 2001
+From: Dave Taht <[email protected]>
+Date: Tue, 15 Dec 2015 17:19:14 +0100
+Subject: [PATCH] perf fixes for musl
+
+---
+ tools/lib/api/fs/tracing_path.c    |  3 +++
+ tools/lib/traceevent/event-parse.c |  4 ++++
+ tools/perf/perf.c                  | 17 ++++++++++++++++-
+ tools/perf/util/cache.h            |  2 +-
+ tools/perf/util/cloexec.c          |  4 ----
+ tools/perf/util/cloexec.h          |  4 ----
+ tools/perf/util/util.h             |  4 ++++
+ 7 files changed, 28 insertions(+), 10 deletions(-)
+
+diff --git a/tools/lib/api/fs/tracing_path.c b/tools/lib/api/fs/tracing_path.c
+index a26bb5e..a04df38 100644
+--- a/tools/lib/api/fs/tracing_path.c
++++ b/tools/lib/api/fs/tracing_path.c
+@@ -10,6 +10,9 @@
+ #include "fs.h"
+ 
+ #include "tracing_path.h"
++/* musl has a xpg compliant strerror_r by default */
++#define strerror_r(err, buf, buflen) \
++        (strerror_r(err, buf, buflen) ? NULL : buf)
+ 
+ 
+ char tracing_mnt[PATH_MAX]         = "/sys/kernel/debug";
+diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
+index 2a912df..0644b42 100644
+--- a/tools/lib/traceevent/event-parse.c
++++ b/tools/lib/traceevent/event-parse.c
+@@ -36,6 +36,10 @@
+ #include "event-parse.h"
+ #include "event-utils.h"
+ 
++/* musl has a xpg compliant strerror_r by default */
++#define strerror_r(err, buf, buflen) \
++        (strerror_r(err, buf, buflen) ? NULL : buf)
++
+ static const char *input_buf;
+ static unsigned long long input_buf_ptr;
+ static unsigned long long input_buf_siz;
+diff --git a/tools/perf/perf.c b/tools/perf/perf.c
+index 3d4c7c0..91f57b0 100644
+--- a/tools/perf/perf.c
++++ b/tools/perf/perf.c
+@@ -523,6 +523,21 @@ void pthread__unblock_sigwinch(void)
+ 	pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+ }
+ 
++unsigned cache_line_size(void);
++
++unsigned cache_line_size(void) {
++	FILE * p = 0;
++	unsigned int i = 0;
++	p = fopen("/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size", "r");
++	if (p) {
++		if(fscanf(p, "%d", &i) != 1) {
++			perror("cannot determine cache line size");
++		}
++		fclose(p);
++	}
++	return i;
++}
++
+ int main(int argc, const char **argv)
+ {
+ 	const char *cmd;
+@@ -530,7 +545,7 @@ int main(int argc, const char **argv)
+ 
+ 	/* The page_size is placed in util object. */
+ 	page_size = sysconf(_SC_PAGE_SIZE);
+-	cacheline_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
++	cacheline_size = cache_line_size();
+ 
+ 	cmd = perf_extract_argv0_path(argv[0]);
+ 	if (!cmd)
+diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
+index c861373..599aa97 100644
+--- a/tools/perf/util/cache.h
++++ b/tools/perf/util/cache.h
+@@ -71,7 +71,7 @@ extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2
+ extern char *perf_pathdup(const char *fmt, ...)
+ 	__attribute__((format (printf, 1, 2)));
+ 
+-#ifndef __UCLIBC__
++#if !defined(__UCLIBC__) && defined(__GLIBC__) 
+ /* Matches the libc/libbsd function attribute so we declare this unconditionally: */
+ extern size_t strlcpy(char *dest, const char *src, size_t size);
+ #endif
+diff --git a/tools/perf/util/cloexec.c b/tools/perf/util/cloexec.c
+index 2babdda..85b5238 100644
+--- a/tools/perf/util/cloexec.c
++++ b/tools/perf/util/cloexec.c
+@@ -7,15 +7,11 @@
+ 
+ static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
+ 
+-#ifdef __GLIBC_PREREQ
+-#if !__GLIBC_PREREQ(2, 6)
+ int __weak sched_getcpu(void)
+ {
+ 	errno = ENOSYS;
+ 	return -1;
+ }
+-#endif
+-#endif
+ 
+ static int perf_flag_probe(void)
+ {
+diff --git a/tools/perf/util/cloexec.h b/tools/perf/util/cloexec.h
+index 3bee677..06904bc 100644
+--- a/tools/perf/util/cloexec.h
++++ b/tools/perf/util/cloexec.h
+@@ -3,10 +3,6 @@
+ 
+ unsigned long perf_event_open_cloexec_flag(void);
+ 
+-#ifdef __GLIBC_PREREQ
+-#if !__GLIBC_PREREQ(2, 6) && !defined(__UCLIBC__)
+ extern int sched_getcpu(void) __THROW;
+-#endif
+-#endif
+ 
+ #endif /* __PERF_CLOEXEC_H */
+diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
+index dcc6590..16d398b 100644
+--- a/tools/perf/util/util.h
++++ b/tools/perf/util/util.h
+@@ -358,4 +358,8 @@ int fetch_kernel_version(unsigned int *puint,
+ #define KVER_FMT	"%d.%d.%d"
+ #define KVER_PARAM(x)	KVER_VERSION(x), KVER_PATCHLEVEL(x), KVER_SUBLEVEL(x)
+ 
++/* musl has a xpg compliant strerror_r by default */
++#define strerror_r(err, buf, buflen) \
++        (strerror_r(err, buf, buflen) ? NULL : buf)
++
+ #endif /* GIT_COMPAT_UTIL_H */
+-- 
+2.5.0
+
-- 
2.5.0

_______________________________________________
Babel-users mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/babel-users

Reply via email to