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 <hauke@hauke-m.de> SVN-Revision: 48501
This commit is contained in:
parent
0b55a7904b
commit
998f8bd02c
1 changed files with 54 additions and 3 deletions
|
@ -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 <hauke@hauke-m.de>
|
||||
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 <hauke@hauke-m.de>
|
||||
---
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in a new issue