nds32: Fix vDSO clock_getres()
authorVincenzo Frascino <vincenzo.frascino@arm.com>
Mon, 1 Apr 2019 11:51:51 +0000 (12:51 +0100)
committerGreentime Hu <greentime@andestech.com>
Thu, 16 May 2019 07:07:08 +0000 (15:07 +0800)
clock_getres in the vDSO library has to preserve the same behaviour
of posix_get_hrtimer_res().

In particular, posix_get_hrtimer_res() does:
    sec = 0;
    ns = hrtimer_resolution;
and hrtimer_resolution depends on the enablement of the high
resolution timers that can happen either at compile or at run time.

Fix the nds32 vdso implementation of clock_getres keeping a copy of
hrtimer_resolution in vdso data and using that directly.

Cc: Greentime Hu <green.hu@gmail.com>
Cc: Vincent Chen <deanbo422@gmail.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Signed-off-by: Greentime Hu <greentime@andestech.com>
arch/nds32/include/asm/vdso_datapage.h
arch/nds32/kernel/vdso.c
arch/nds32/kernel/vdso/gettimeofday.c

index cd1dda3da0f930708664b12c26197865414d8948..74c68802021ec60d277292e2e86b3043c0535ed2 100644 (file)
@@ -20,6 +20,7 @@ struct vdso_data {
        u32 xtime_clock_sec;    /* CLOCK_REALTIME - seconds */
        u32 cs_mult;            /* clocksource multiplier */
        u32 cs_shift;           /* Cycle to nanosecond divisor (power of two) */
+       u32 hrtimer_res;        /* hrtimer resolution */
 
        u64 cs_cycle_last;      /* last cycle value */
        u64 cs_mask;            /* clocksource mask */
index 016f15891f6d40c22a908a6da6c719c5a3c6503a..90bcae6f855448da7775863d9d172ce0fbaae9b4 100644 (file)
@@ -220,6 +220,7 @@ void update_vsyscall(struct timekeeper *tk)
        vdso_data->xtime_coarse_sec = tk->xtime_sec;
        vdso_data->xtime_coarse_nsec = tk->tkr_mono.xtime_nsec >>
            tk->tkr_mono.shift;
+       vdso_data->hrtimer_res = hrtimer_resolution;
        vdso_write_end(vdso_data);
 }
 
index 038721af40e37d91213f8de6bd636b8c03cfeae8..b02581891c33c7288d1db33a58dbeff5eb1ad6cf 100644 (file)
@@ -208,6 +208,8 @@ static notrace int clock_getres_fallback(clockid_t _clk_id,
 
 notrace int __vdso_clock_getres(clockid_t clk_id, struct timespec *res)
 {
+       struct vdso_data *vdata = __get_datapage();
+
        if (res == NULL)
                return 0;
        switch (clk_id) {
@@ -215,7 +217,7 @@ notrace int __vdso_clock_getres(clockid_t clk_id, struct timespec *res)
        case CLOCK_MONOTONIC:
        case CLOCK_MONOTONIC_RAW:
                res->tv_sec = 0;
-               res->tv_nsec = CLOCK_REALTIME_RES;
+               res->tv_nsec = vdata->hrtimer_res;
                break;
        case CLOCK_REALTIME_COARSE:
        case CLOCK_MONOTONIC_COARSE: