Commit 886653e3 authored by Anna-Maria Behnsen's avatar Anna-Maria Behnsen Committed by Thomas Gleixner
Browse files

vdso: Rework struct vdso_time_data and introduce struct vdso_clock



To support multiple PTP clocks, the VDSO data structure needs to be
reworked. All clock specific data will end up in struct vdso_clock and in
struct vdso_time_data there will be an array of VDSO clocks.

Now that all preparatory changes are in place:

Split the clock related struct members into a separate struct
vdso_clock. Make sure all users are aware, that vdso_time_data is no longer
initialized as an array and vdso_clock is now the array inside
vdso_data. Remove the vdso_clock define, which mapped it to vdso_time_data
for the transition.

Signed-off-by: default avatarAnna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: default avatarNam Cao <namcao@linutronix.de>
Signed-off-by: default avatarThomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250303-vdso-clock-v1-19-c1b5c69a166f@linutronix.de
parent 97a5a90c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -149,7 +149,7 @@ static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(
	 * where __aarch64_get_vdso_u_time_data() is called, and then keep the
	 * result in a register.
	 */
	asm volatile("mov %0, %1" : "=r"(ret) : "r"(vdso_u_time_data));
	asm volatile("mov %0, %1" : "=r"(ret) : "r"(&vdso_u_time_data));

	return ret;
}
+2 −2
Original line number Diff line number Diff line
@@ -15,8 +15,8 @@
static __always_inline
void __arm64_update_vsyscall(struct vdso_time_data *vdata)
{
	vdata[CS_HRES_COARSE].mask	= VDSO_PRECISION_MASK;
	vdata[CS_RAW].mask		= VDSO_PRECISION_MASK;
	vdata->clock_data[CS_HRES_COARSE].mask	= VDSO_PRECISION_MASK;
	vdata->clock_data[CS_RAW].mask		= VDSO_PRECISION_MASK;
}
#define __arch_update_vsyscall __arm64_update_vsyscall

+3 −8
Original line number Diff line number Diff line
@@ -79,12 +79,10 @@ void __init time_early_init(void)
{
	struct ptff_qto qto;
	struct ptff_qui qui;
	int cs;

	/* Initialize TOD steering parameters */
	tod_steering_end = tod_clock_base.tod;
	for (cs = 0; cs < CS_BASES; cs++)
		vdso_k_time_data[cs].arch_data.tod_steering_end = tod_steering_end;
	vdso_k_time_data->arch_data.tod_steering_end = tod_steering_end;

	if (!test_facility(28))
		return;
@@ -373,7 +371,6 @@ static void clock_sync_global(long delta)
{
	unsigned long now, adj;
	struct ptff_qto qto;
	int cs;

	/* Fixup the monotonic sched clock. */
	tod_clock_base.eitod += delta;
@@ -389,10 +386,8 @@ static void clock_sync_global(long delta)
		panic("TOD clock sync offset %li is too large to drift\n",
		      tod_steering_delta);
	tod_steering_end = now + (abs(tod_steering_delta) << 15);
	for (cs = 0; cs < CS_BASES; cs++) {
		vdso_k_time_data[cs].arch_data.tod_steering_end = tod_steering_end;
		vdso_k_time_data[cs].arch_data.tod_steering_delta = tod_steering_delta;
	}
	vdso_k_time_data->arch_data.tod_steering_end = tod_steering_end;
	vdso_k_time_data->arch_data.tod_steering_delta = tod_steering_delta;

	/* Update LPAR offset. */
	if (ptff_query(PTFF_QTO) && ptff(&qto, sizeof(qto), PTFF_QTO) == 0)
+1 −1
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
#ifndef __arch_get_vdso_u_time_data
static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(void)
{
	return vdso_u_time_data;
	return &vdso_u_time_data;
}
#endif

+32 −23
Original line number Diff line number Diff line
@@ -69,9 +69,7 @@ struct vdso_timestamp {
};

/**
 * struct vdso_time_data - vdso datapage representation
 * @arch_data:		architecture specific data (optional, defaults
 *			to an empty struct)
 * struct vdso_clock - vdso per clocksource datapage representation
 * @seq:		timebase sequence counter
 * @clock_mode:		clock mode
 * @cycle_last:		timebase at clocksource init
@@ -81,17 +79,9 @@ struct vdso_timestamp {
 * @shift:		clocksource shift
 * @basetime[clock_id]:	basetime per clock_id
 * @offset[clock_id]:	time namespace offset per clock_id
 * @tz_minuteswest:	minutes west of Greenwich
 * @tz_dsttime:		type of DST correction
 * @hrtimer_res:	hrtimer resolution
 * @__unused:		unused
 *
 * vdso_time_data will be accessed by 64 bit and compat code at the same time
 * so we should be careful before modifying this structure.
 *
 * The ordering of the struct members is optimized to have fast access to the
 * often required struct members which are related to CLOCK_REALTIME and
 * CLOCK_MONOTONIC. This information is stored in the first cache lines.
 * See also struct vdso_time_data for basic access and ordering information as
 * struct vdso_clock is used there.
 *
 * @basetime is used to store the base time for the system wide time getter
 * VVAR page.
@@ -104,9 +94,7 @@ struct vdso_timestamp {
 * For clocks which are not affected by time namespace adjustment the
 * offset must be zero.
 */
struct vdso_time_data {
	struct arch_vdso_time_data arch_data;

struct vdso_clock {
	u32			seq;

	s32			clock_mode;
@@ -122,6 +110,29 @@ struct vdso_time_data {
		struct vdso_timestamp	basetime[VDSO_BASES];
		struct timens_offset	offset[VDSO_BASES];
	};
};

/**
 * struct vdso_time_data - vdso datapage representation
 * @arch_data:		architecture specific data (optional, defaults
 *			to an empty struct)
 * @clock_data:		clocksource related data (array)
 * @tz_minuteswest:	minutes west of Greenwich
 * @tz_dsttime:		type of DST correction
 * @hrtimer_res:	hrtimer resolution
 * @__unused:		unused
 *
 * vdso_time_data will be accessed by 64 bit and compat code at the same time
 * so we should be careful before modifying this structure.
 *
 * The ordering of the struct members is optimized to have fast acces to the
 * often required struct members which are related to CLOCK_REALTIME and
 * CLOCK_MONOTONIC. This information is stored in the first cache lines.
 */
struct vdso_time_data {
	struct arch_vdso_time_data	arch_data;

	struct vdso_clock		clock_data[CS_BASES];

	s32				tz_minuteswest;
	s32				tz_dsttime;
@@ -129,8 +140,6 @@ struct vdso_time_data {
	u32				__unused;
} ____cacheline_aligned;

#define vdso_clock vdso_time_data

/**
 * struct vdso_rng_data - vdso RNG state information
 * @generation:	counter representing the number of RNG reseeds
@@ -151,7 +160,7 @@ struct vdso_rng_data {
 * relocation, and this is what we need.
 */
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
extern struct vdso_time_data vdso_u_time_data[CS_BASES] __attribute__((visibility("hidden")));
extern struct vdso_time_data vdso_u_time_data __attribute__((visibility("hidden")));
extern struct vdso_rng_data vdso_u_rng_data __attribute__((visibility("hidden")));
extern struct vdso_arch_data vdso_u_arch_data __attribute__((visibility("hidden")));

Loading