[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <alpine.DEB.2.21.1905281055240.1859@nanos.tec.linutronix.de>
Date: Tue, 28 May 2019 11:01:38 -0700 (PDT)
From: Thomas Gleixner <tglx@...utronix.de>
To: "Sverdlin, Alexander (Nokia - DE/Ulm)" <alexander.sverdlin@...ia.com>
cc: "x86@...nel.org" <x86@...nel.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
Andy Lutomirski <luto@...nel.org>,
Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
"H. Peter Anvin" <hpa@...or.com>,
Jason Vas Dias <jason.vas.dias@...il.com>
Subject: Re: [PATCH] x86/vdso: implement clock_gettime(CLOCK_MONOTONIC_RAW,
...)
Alexander,
On Tue, 28 May 2019, Sverdlin, Alexander (Nokia - DE/Ulm) wrote:
> Add CLOCK_MONOTONIC_RAW to the existing clock_gettime() vDSO
> implementation. This is based on the ideas of Jason Vas Dias and comments
> of Thomas Gleixner.
Well to some extent, but
> The results from the above test program:
>
> Clock Before After Diff
> ----- ------ ----- ----
> CLOCK_MONOTONIC 355531720 338039373 -5%
> CLOCK_MONOTONIC_RAW 44831738 336064912 +650%
> CLOCK_REALTIME 347665133 338102907 -3%
the preformance regressions for CLOCK_MONOTONIC and CLOCK_REALTIME are just
not acceptable.
> diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c
> index 98c7d12..7c9db26 100644
> --- a/arch/x86/entry/vdso/vclock_gettime.c
> +++ b/arch/x86/entry/vdso/vclock_gettime.c
> @@ -144,6 +144,13 @@ notrace static int do_hres(clockid_t clk, struct timespec *ts)
> struct vgtod_ts *base = >od->basetime[clk];
> u64 cycles, last, sec, ns;
> unsigned int seq;
> + u32 mult = gtod->mult;
> + u32 shift = gtod->shift;
> +
> + if (clk == CLOCK_MONOTONIC_RAW) {
> + mult = gtod->raw_mult;
> + shift = gtod->raw_shift;
> + }
They stem from this extra conditional.
>
> do {
> seq = gtod_read_begin(gtod);
> @@ -153,8 +160,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) * mult;
And this is completely broken because you read the mult/shift values
outside of the sequence count protected region, so a concurrent update of
the timekeeping values will lead to inconsistent state.
Thanks,
tglx
Powered by blists - more mailing lists