From: Alexander Sverdlin <[email protected]>

This is a preparation for CLOCK_MONOTONIC_RAW vDSO implementation.
Coincidentally it had a slight performance improvement as well:

---- Test code ----
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
 #include <unistd.h>

 #define CLOCK_TYPE CLOCK_MONOTONIC_RAW
 #define DURATION_SEC 10

int main(int argc, char **argv)
{
        struct timespec t, end;
        unsigned long long cnt = 0;

        clock_gettime(CLOCK_TYPE, &end);
        end.tv_sec += DURATION_SEC;

        do {
                clock_gettime(CLOCK_TYPE, &t);
                ++cnt;
        } while (t.tv_sec < end.tv_sec || t.tv_nsec < end.tv_nsec);

        dprintf(STDOUT_FILENO, "%llu", cnt);

        return EXIT_SUCCESS;
}
-------------------

The results from the above test program:

Clock                   Before  After   Diff
-----                   ------  -----   ----
CLOCK_MONOTONIC         355.5M  359.6M  +1%
CLOCK_REALTIME          355.5M  359.6M  +1%

Cc: Thomas Gleixner <[email protected]>
Cc: Jason Vas Dias <[email protected]>
Suggested-by: Andy Lutomirski <[email protected]>
Signed-off-by: Alexander Sverdlin <[email protected]>
---
 arch/x86/entry/vdso/vclock_gettime.c    | 4 ++--
 arch/x86/entry/vsyscall/vsyscall_gtod.c | 8 ++++++--
 arch/x86/include/asm/vgtod.h            | 4 ++--
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/x86/entry/vdso/vclock_gettime.c 
b/arch/x86/entry/vdso/vclock_gettime.c
index 0f82a70..a99eaf5 100644
--- a/arch/x86/entry/vdso/vclock_gettime.c
+++ b/arch/x86/entry/vdso/vclock_gettime.c
@@ -153,8 +153,8 @@ notrace static int do_hres(clockid_t clk, struct timespec 
*ts)
                if (unlikely((s64)cycles < 0))
                        return vdso_fallback_gettime(clk, ts);
                if (cycles > last)
-                       ns += (cycles - last) * gtod->mult;
-               ns >>= gtod->shift;
+                       ns += (cycles - last) * base->mult;
+               ns >>= base->shift;
                sec = base->sec;
        } while (unlikely(gtod_read_retry(gtod, seq)));
 
diff --git a/arch/x86/entry/vsyscall/vsyscall_gtod.c 
b/arch/x86/entry/vsyscall/vsyscall_gtod.c
index cfcdba0..64b1e7c 100644
--- a/arch/x86/entry/vsyscall/vsyscall_gtod.c
+++ b/arch/x86/entry/vsyscall/vsyscall_gtod.c
@@ -44,16 +44,18 @@ void update_vsyscall(struct timekeeper *tk)
        vdata->vclock_mode      = vclock_mode;
        vdata->cycle_last       = tk->tkr_mono.cycle_last;
        vdata->mask             = tk->tkr_mono.mask;
-       vdata->mult             = tk->tkr_mono.mult;
-       vdata->shift            = tk->tkr_mono.shift;
 
        base = &vdata->basetime[CLOCK_REALTIME];
        base->sec = tk->xtime_sec;
        base->nsec = tk->tkr_mono.xtime_nsec;
+       base->mult = tk->tkr_mono.mult;
+       base->shift = tk->tkr_mono.shift;
 
        base = &vdata->basetime[CLOCK_TAI];
        base->sec = tk->xtime_sec + (s64)tk->tai_offset;
        base->nsec = tk->tkr_mono.xtime_nsec;
+       base->mult = tk->tkr_mono.mult;
+       base->shift = tk->tkr_mono.shift;
 
        base = &vdata->basetime[CLOCK_MONOTONIC];
        base->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
@@ -64,6 +66,8 @@ void update_vsyscall(struct timekeeper *tk)
                base->sec++;
        }
        base->nsec = nsec;
+       base->mult = tk->tkr_mono.mult;
+       base->shift = tk->tkr_mono.shift;
 
        base = &vdata->basetime[CLOCK_REALTIME_COARSE];
        base->sec = tk->xtime_sec;
diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h
index 913a133..b1f6df3 100644
--- a/arch/x86/include/asm/vgtod.h
+++ b/arch/x86/include/asm/vgtod.h
@@ -25,6 +25,8 @@ typedef unsigned long gtod_long_t;
 struct vgtod_ts {
        u64             sec;
        u64             nsec;
+       u32             mult;
+       u32             shift;
 };
 
 #define VGTOD_BASES    (CLOCK_TAI + 1)
@@ -41,8 +43,6 @@ struct vsyscall_gtod_data {
        int             vclock_mode;
        u64             cycle_last;
        u64             mask;
-       u32             mult;
-       u32             shift;
 
        struct vgtod_ts basetime[VGTOD_BASES];
 
-- 
2.4.6

Reply via email to