Message ID | 1451384084-5093-1-git-send-email-kevin@darbyshire-bryant.me.uk |
---|---|
State | Superseded |
Headers | show |
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@bufferbloat.net> who > did the heavy lifting. > > Signed-off-by: Kevin Darbyshire-Bryant <kevin@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@bufferbloat.net> for the heavy lifting. > + > +Signed-off-by: Kevin Darbyshire-Bryant <kevin@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@bufferbloat.net> for the > +heavy lifting. > + > +Signed-off-by: Kevin Darbyshire-Bryant <kevin@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 > + >
On 29/12/15 11:13, Hauke Mehrtens wrote: > > 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@bufferbloat.net> who >> did the heavy lifting. >> >> Signed-off-by: Kevin Darbyshire-Bryant <kevin@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 Hi Hauke, Let me prefix this with "I don't know what I'm doing" > 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 suspect it'll break spectacularly with glibc. I'm sure the patches could be modified to have both glibc & musl compatibility but it's beyond my wit to know how. I was interested in getting perf to work (without enabling broken packages) under Archer C7 v2 which uses musl now by default. I've no idea about 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 Now that's something I can do....if it's worth the bother bearing in mind other comments? > > Will this be in kernel 4.5? No idea. My Archer (ar71xx) isn't on 4.4 yet let alone 4.5 A few people have put effort into getting perf running on the above mentioned platforms, I thought it worth throwing at OpenWrt devel list as a patch to pass the effort on and see what sticks :-) If it doesn't stick then fair enough. Kevin
On 29 December 2015 at 12:14, Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk> 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@bufferbloat.net> who > did the heavy lifting. > > Signed-off-by: Kevin Darbyshire-Bryant <kevin@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 > 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@bufferbloat.net> for the heavy lifting. > + > +Signed-off-by: Kevin Darbyshire-Bryant <kevin@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; > ++} > ++ Kevin, are you sure this works? I don't have /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size on my Archer C7 I did a little bit more simple way adding a header from eglibc. If anybody interested I can submit the patch for RFC. Regards, Roman
On 31/12/15 12:22, Roman Yeryomin wrote: > On 29 December 2015 at 12:14, Kevin Darbyshire-Bryant > <kevin@darbyshire-bryant.me.uk> wrote: > > Kevin, are you sure this works? > I don't have /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size > on my Archer C7 Hi Roman, Perf ran and didn't barf when I tried...however I'm new to perf so maybe I didn't look in the right place. I also wonder if that sys file entry is only enabled when kernel perf config is enabled too. > I did a little bit more simple way adding a header from eglibc. If > anybody interested I can submit the patch for RFC. Personally, I'd say anything that helps performance investigations on 'under powered' SoC devices is a good thing, helpful & useful. Kevin > > > Regards, > Roman
On 2015-12-31 13:22, Roman Yeryomin wrote: > Kevin, are you sure this works? > I don't have /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size > on my Archer C7 > I did a little bit more simple way adding a header from eglibc. If > anybody interested I can submit the patch for RFC. As far as I can see, glibc only supports reading the cache line size for few architectures, probably fewer than those that provide the sysfs file. I don't see a generic way to query this on mips and the return code should be the same as sysconf on uclibc/glibc, so this function makes sense. It should probably be made static though... - Felix
On 2015-12-29 11:14, 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@bufferbloat.net> who > did the heavy lifting. > > Signed-off-by: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk> FYI, I just did some cleanups and fixes on perf, and it now builds and runs on musl without any extra kernel patches. - Felix
On 02/01/16 14:49, Felix Fietkau wrote: > On 2015-12-29 11:14, 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@bufferbloat.net> who >> did the heavy lifting. >> >> Signed-off-by: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk> > FYI, I just did some cleanups and fixes on perf, and it now builds and > runs on musl without any extra kernel patches. > > - Felix That's great Felix! Thank you. Kevin
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 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@bufferbloat.net> for the heavy lifting. + +Signed-off-by: Kevin Darbyshire-Bryant <kevin@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@bufferbloat.net> for the +heavy lifting. + +Signed-off-by: Kevin Darbyshire-Bryant <kevin@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 +
Enable linux perf tools to compile under musl. Tested on MIPS Archer c7 v2 & ARM Linksys 1200ac. With thanks to Dave Taht <dave.taht@bufferbloat.net> who did the heavy lifting. Signed-off-by: Kevin Darbyshire-Bryant <kevin@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