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
+
