mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 08:58:07 +00:00
19d0070a27
Architectures can have the requirement to add additional architecture specific data to the VDSO data page which needs to be updated independent of the timekeeper updates. To protect these updates vs. concurrent readers and a conflicting update through timekeeping, provide helper functions to make such updates safe. vdso_update_begin() takes the timekeeper_lock to protect against a potential update from timekeeper code and increments the VDSO sequence count to signal data inconsistency to concurrent readers. vdso_update_end() makes the sequence count even again to signal data consistency and drops the timekeeper lock. [ Sven: Add interrupt disable handling to the functions ] Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Sven Schnelle <svens@linux.ibm.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lkml.kernel.org/r/20200804150124.41692-3-svens@linux.ibm.com
39 lines
921 B
C
39 lines
921 B
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _TIMEKEEPING_INTERNAL_H
|
|
#define _TIMEKEEPING_INTERNAL_H
|
|
|
|
#include <linux/clocksource.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/time.h>
|
|
|
|
/*
|
|
* timekeeping debug functions
|
|
*/
|
|
#ifdef CONFIG_DEBUG_FS
|
|
extern void tk_debug_account_sleep_time(const struct timespec64 *t);
|
|
#else
|
|
#define tk_debug_account_sleep_time(x)
|
|
#endif
|
|
|
|
#ifdef CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE
|
|
static inline u64 clocksource_delta(u64 now, u64 last, u64 mask)
|
|
{
|
|
u64 ret = (now - last) & mask;
|
|
|
|
/*
|
|
* Prevent time going backwards by checking the MSB of mask in
|
|
* the result. If set, return 0.
|
|
*/
|
|
return ret & ~(mask >> 1) ? 0 : ret;
|
|
}
|
|
#else
|
|
static inline u64 clocksource_delta(u64 now, u64 last, u64 mask)
|
|
{
|
|
return (now - last) & mask;
|
|
}
|
|
#endif
|
|
|
|
/* Semi public for serialization of non timekeeper VDSO updates. */
|
|
extern raw_spinlock_t timekeeper_lock;
|
|
|
|
#endif /* _TIMEKEEPING_INTERNAL_H */
|