Commit 01162068 authored by Heiko Carstens's avatar Heiko Carstens Committed by Vasily Gorbik

s390/time: ensure get_clock_monotonic() returns monotonic values

The current implementation of get_clock_monotonic() leaves it up to
the caller to call the function with preemption disabled. The only
core kernel caller (sched_clock) however does not disable preemption.

In order to make sure that all callers of this function see monotonic
values handle disabling preemption within the function itself.
Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 6756dd9b
...@@ -10,8 +10,9 @@ ...@@ -10,8 +10,9 @@
#ifndef _ASM_S390_TIMEX_H #ifndef _ASM_S390_TIMEX_H
#define _ASM_S390_TIMEX_H #define _ASM_S390_TIMEX_H
#include <asm/lowcore.h> #include <linux/preempt.h>
#include <linux/time64.h> #include <linux/time64.h>
#include <asm/lowcore.h>
/* The value of the TOD clock for 1.1.1970. */ /* The value of the TOD clock for 1.1.1970. */
#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL #define TOD_UNIX_EPOCH 0x7d91048bca000000ULL
...@@ -185,15 +186,18 @@ extern unsigned char tod_clock_base[16] __aligned(8); ...@@ -185,15 +186,18 @@ extern unsigned char tod_clock_base[16] __aligned(8);
/** /**
* get_clock_monotonic - returns current time in clock rate units * get_clock_monotonic - returns current time in clock rate units
* *
* The caller must ensure that preemption is disabled.
* The clock and tod_clock_base get changed via stop_machine. * The clock and tod_clock_base get changed via stop_machine.
* Therefore preemption must be disabled when calling this * Therefore preemption must be disabled, otherwise the returned
* function, otherwise the returned value is not guaranteed to * value is not guaranteed to be monotonic.
* be monotonic.
*/ */
static inline unsigned long long get_tod_clock_monotonic(void) static inline unsigned long long get_tod_clock_monotonic(void)
{ {
return get_tod_clock() - *(unsigned long long *) &tod_clock_base[1]; unsigned long long tod;
preempt_disable();
tod = get_tod_clock() - *(unsigned long long *) &tod_clock_base[1];
preempt_enable();
return tod;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment