Commit eec399dd authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

x86/vdso: Move VDSO clocksource state tracking to callback



All architectures which use the generic VDSO code have their own storage
for the VDSO clock mode. That's pointless and just requires duplicate code.

X86 abuses the function which retrieves the architecture specific clock
mode storage to mark the clocksource as used in the VDSO. That's silly
because this is invoked on every tick when the VDSO data is updated.

Move this functionality to the clocksource::enable() callback so it gets
invoked once when the clocksource is installed. This allows to make the
clock mode storage generic.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>  (Hyper-V parts)
Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com> (VDSO parts)
Acked-by: Juergen Gross <jgross@suse.com> (Xen parts)
Link: https://lkml.kernel.org/r/20200207124402.934519777@linutronix.de
parent 3bd142a4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ struct vdso_data *arch_get_vdso_data(void *vvar_page)
}
#undef EMIT_VVAR

unsigned int vclocks_used __read_mostly;

#if defined(CONFIG_X86_64)
unsigned int __read_mostly vdso64_enabled = 1;
#endif
@@ -445,6 +447,8 @@ __setup("vdso=", vdso_setup);

static int __init init_vdso(void)
{
	BUILD_BUG_ON(VCLOCK_MAX >= 32);

	init_vdso_image(&vdso_image_64);

#ifdef CONFIG_X86_X32_ABI
+12 −0
Original line number Diff line number Diff line
@@ -14,4 +14,16 @@ struct arch_clocksource_data {
	int vclock_mode;
};

extern unsigned int vclocks_used;

static inline bool vclock_was_used(int vclock)
{
	return READ_ONCE(vclocks_used) & (1U << vclock);
}

static inline void vclocks_set_used(unsigned int which)
{
	WRITE_ONCE(vclocks_used, READ_ONCE(vclocks_used) | (1 << which));
}

#endif /* _ASM_X86_CLOCKSOURCE_H */
+2 −0
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ typedef int (*hyperv_fill_flush_list_func)(
	wrmsrl(HV_X64_MSR_REFERENCE_TSC, val)
#define hv_set_clocksource_vdso(val) \
	((val).archdata.vclock_mode = VCLOCK_HVCLOCK)
#define hv_enable_vdso_clocksource() \
	vclocks_set_used(VCLOCK_HVCLOCK);
#define hv_get_raw_timer() rdtsc_ordered()

void hyperv_callback_vector(void);
+1 −9
Original line number Diff line number Diff line
@@ -10,8 +10,6 @@
#include <asm/vgtod.h>
#include <asm/vvar.h>

int vclocks_used __read_mostly;

DEFINE_VVAR(struct vdso_data, _vdso_data);
/*
 * Update the vDSO data page to keep in sync with kernel timekeeping.
@@ -26,13 +24,7 @@ struct vdso_data *__x86_get_k_vdso_data(void)
static __always_inline
int __x86_get_clock_mode(struct timekeeper *tk)
{
	int vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode;

	/* Mark the new vclock used. */
	BUILD_BUG_ON(VCLOCK_MAX >= 32);
	WRITE_ONCE(vclocks_used, READ_ONCE(vclocks_used) | (1 << vclock_mode));

	return vclock_mode;
	return tk->tkr_mono.clock->archdata.vclock_mode;
}
#define __arch_get_clock_mode __x86_get_clock_mode

+0 −6
Original line number Diff line number Diff line
@@ -15,10 +15,4 @@ typedef u64 gtod_long_t;
typedef unsigned long gtod_long_t;
#endif

extern int vclocks_used;
static inline bool vclock_was_used(int vclock)
{
	return READ_ONCE(vclocks_used) & (1 << vclock);
}

#endif /* _ASM_X86_VGTOD_H */
Loading