[OpenWrt-Devel] [PATCH] kernel: generic 4.1 & 4.4 perf: musl compatibility

Hauke Mehrtens hauke at hauke-m.de
Tue Dec 29 06:13:03 EST 2015



On 12/29/2015 11:14 AM, Kevin Darbyshire-Bryant wrote:
> Enable linux perf tools to compile under musl.
> 
> Tested on MIPS Archer c7 v2 & ARM Linksys 1200ac.
> 
> With thanks to Dave Taht <dave.taht at bufferbloat.net> who
> did the heavy lifting.
> 
> Signed-off-by: Kevin Darbyshire-Bryant <kevin at darbyshire-bryant.me.uk>
> ---
>  package/devel/perf/Makefile                        |   2 +-
>  .../patches-4.1/280-perf-fixes-for-musl.patch      | 148 +++++++++++++++++++++
>  .../patches-4.4/280-perf-fixes-for-musl.patch      | 147 ++++++++++++++++++++
>  3 files changed, 296 insertions(+), 1 deletion(-)
>  create mode 100644 target/linux/generic/patches-4.1/280-perf-fixes-for-musl.patch
>  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..46ddb92 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:= @USE_MUSL +libelf1 +libdw +libpthread +librt +binutils

Does it not work with GLIBC any more or why do you make it depend on
musl only now? Does this work with uclibc-ng?

I assume that this will not work on kernel 3.18 and kernel 4.3, which is
fine, as you haven't added patches for these kernel versions, but the
dependency is missing. Please add @!LINUX_3_18 @!LINUX_4_3

Will this be in kernel 4.5?

>    TITLE:=Linux performance monitoring tool
>    VERSION:=$(LINUX_VERSION)-$(PKG_RELEASE)
>    URL:=http://www.kernel.org
> diff --git a/target/linux/generic/patches-4.1/280-perf-fixes-for-musl.patch b/target/linux/generic/patches-4.1/280-perf-fixes-for-musl.patch
> new file mode 100644
> index 0000000..0e8b6d8
> --- /dev/null
> +++ b/target/linux/generic/patches-4.1/280-perf-fixes-for-musl.patch
> @@ -0,0 +1,148 @@
> +kernel: 4.1 perf: musl compatibility
> +
> +Allow linux perf tool to compile under musl.
> +
> +Backport to 4.1 by Kevin D-B with thanks to Dave
> +Taht <dave.taht at bufferbloat.net> for the heavy lifting.
> +
> +Signed-off-by: Kevin Darbyshire-Bryant <kevin at darbyshire-bryant.me.uk>
> +
> +---
> + tools/lib/api/fs/debugfs.c         |  4 ++++
> + 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, 29 insertions(+), 10 deletions(-)
> +
> +diff --git a/tools/lib/api/fs/debugfs.c b/tools/lib/api/fs/debugfs.c
> +index 8305b3e..5d1745c 100644
> +--- a/tools/lib/api/fs/debugfs.c
> ++++ b/tools/lib/api/fs/debugfs.c
> +@@ -17,6 +17,10 @@
> + #define DEBUGFS_DEFAULT_PATH		"/sys/kernel/debug"
> + #endif
> + 
> ++/* musl has a xpg compliant strerror_r by default */
> ++#define strerror_r(err, buf, buflen) \
> ++	(strerror_r(err, buf, buflen) ? NULL : buf)
> ++
> + char debugfs_mountpoint[PATH_MAX + 1] = DEBUGFS_DEFAULT_PATH;
> + 
> + static const char * const debugfs_known_mountpoints[] = {
> +diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
> +index ed5461f..f151369 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 b857fcb..3e67fa2 100644
> +--- a/tools/perf/perf.c
> ++++ b/tools/perf/perf.c
> +@@ -505,6 +505,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;
> +@@ -512,7 +527,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 fbcca21..9b23c4a 100644
> +--- a/tools/perf/util/cache.h
> ++++ b/tools/perf/util/cache.h
> +@@ -72,7 +72,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 68888c2..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)
> + 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 1ff23e0..a5f4770 100644
> +--- a/tools/perf/util/util.h
> ++++ b/tools/perf/util/util.h
> +@@ -333,4 +333,8 @@ int gzip_decompress_to_file(const char *input, int output_fd);
> + int lzma_decompress_to_file(const char *input, int output_fd);
> + #endif
> + 
> ++/* 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 */
> +-- 
> +1.9.1
> +
> 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..42d0d48
> --- /dev/null
> +++ b/target/linux/generic/patches-4.4/280-perf-fixes-for-musl.patch
> @@ -0,0 +1,147 @@
> +kernel: 4.4 perf: musl compatibility
> +
> +Allow linux perf tool to compile under musl.
> +
> +Thanks to Dave Taht <dave.taht at bufferbloat.net> for the
> +heavy lifting.
> +
> +Signed-off-by: Kevin Darbyshire-Bryant <kevin at darbyshire-bryant.me.uk>
> +
> +---
> + 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
> +
> 
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list