From 998f8bd02c128e0c0dcc6a8228ae5aabfec05468 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Mon, 25 Jan 2016 23:26:19 +0000 Subject: [PATCH] musl: fix mips vdso handling mips returns -ENOSYS in case it can not handle the vdso call and wants the libc to call the original syscall in such a case. This fixes the patch to add such handling. I hope this fixes the random reboots I got. Signed-off-by: Hauke Mehrtens SVN-Revision: 48501 --- .../patches/030-mips-add-vdso-support.patch | 57 ++++++++++++++++++- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/toolchain/musl/patches/030-mips-add-vdso-support.patch b/toolchain/musl/patches/030-mips-add-vdso-support.patch index e4a15e323b2..537a1ca0b43 100644 --- a/toolchain/musl/patches/030-mips-add-vdso-support.patch +++ b/toolchain/musl/patches/030-mips-add-vdso-support.patch @@ -1,4 +1,4 @@ -From c29a29c3334344e0f3cfdec6130a6261514507a0 Mon Sep 17 00:00:00 2001 +From 93332ebdcd54b0e0c0e86bced537cc96247bc1f1 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 23 Jan 2016 16:23:09 +0100 Subject: [PATCH 2/2] mips: add vdso support @@ -7,10 +7,32 @@ vdso support is available on mips starting with kernel 4.4, see kernel commit a7f4df4e21 "MIPS: VDSO: Add implementations of gettimeofday() and clock_gettime()" for details. +In Linux kernel 4.4.0 the mips code returns -ENOSYS in case it can not +handle the vdso call and assumes the libc will call the original +syscall in this case. Handle this case in musl. Currently Linux kernel +4.4.0 handles the following types: CLOCK_REALTIME_COARSE, +CLOCK_MONOTONIC_COARSE, CLOCK_REALTIME and CLOCK_MONOTONIC. + +These are some measurements of calling clock_gettime(CLOCK_MONOTONIC, +&tp); 1.000.000 times. + +without vdso: +root@OpenWrt:/# time ./vdso-test +real 0m 0.95s +user 0m 0.24s +sys 0m 0.70s + +with vdso: +root@OpenWrt:/# time /usr/bin/vdso-test +real 0m 0.35s +user 0m 0.34s +sys 0m 0.00s + Signed-off-by: Hauke Mehrtens --- - arch/mips/syscall_arch.h | 4 ++++ - 1 file changed, 4 insertions(+) + arch/mips/syscall_arch.h | 4 ++++ + src/time/clock_gettime.c | 12 +++++++++++- + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/mips/syscall_arch.h b/arch/mips/syscall_arch.h index e74e0ad..39c0ea3 100644 @@ -24,6 +46,35 @@ index e74e0ad..39c0ea3 100644 +#define VDSO_USEFUL +#define VDSO_CGT_SYM "__vdso_clock_gettime" +#define VDSO_CGT_VER "LINUX_2.6" +diff --git a/src/time/clock_gettime.c b/src/time/clock_gettime.c +index 1572de0..dba99ff 100644 +--- a/src/time/clock_gettime.c ++++ b/src/time/clock_gettime.c +@@ -26,13 +26,23 @@ void *__vdsosym(const char *, const char *); + int __clock_gettime(clockid_t clk, struct timespec *ts) + { + #ifdef VDSO_CGT_SYM ++ int ret; + static int (*volatile cgt)(clockid_t, struct timespec *); + if (!cgt) { + void *f = __vdsosym(VDSO_CGT_VER, VDSO_CGT_SYM); + if (!f) f = (void *)sc_clock_gettime; + a_cas_p(&cgt, 0, f); + } +- return cgt(clk, ts); ++ ret = cgt(clk, ts); ++ ++ /* ++ * mips in linux kernel 4.4.0 returns -ENOSYS if it can not ++ * handle the syscall in vdso, the original syscall should be ++ * called by the libc in such a case. ++ */ ++ if (ret == -ENOSYS) ++ return sc_clock_gettime(clk, ts); ++ return ret; + #else + return sc_clock_gettime(clk, ts); + #endif -- 2.7.0.rc3 -- 2.30.2