mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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: Anna-Maria Behnsen <anna-maria@linutronix.de> Signed-off-by: Nam Cao <namcao@linutronix.de> Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/all/20250303-vdso-clock-v1-19-c1b5c69a166f@linutronix.de
		
			
				
	
	
		
			61 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			61 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* SPDX-License-Identifier: GPL-2.0 */
 | 
						|
#ifndef __VDSO_HELPERS_H
 | 
						|
#define __VDSO_HELPERS_H
 | 
						|
 | 
						|
#ifndef __ASSEMBLY__
 | 
						|
 | 
						|
#include <asm/barrier.h>
 | 
						|
#include <vdso/datapage.h>
 | 
						|
 | 
						|
static __always_inline u32 vdso_read_begin(const struct vdso_clock *vc)
 | 
						|
{
 | 
						|
	u32 seq;
 | 
						|
 | 
						|
	while (unlikely((seq = READ_ONCE(vc->seq)) & 1))
 | 
						|
		cpu_relax();
 | 
						|
 | 
						|
	smp_rmb();
 | 
						|
	return seq;
 | 
						|
}
 | 
						|
 | 
						|
static __always_inline u32 vdso_read_retry(const struct vdso_clock *vc,
 | 
						|
					   u32 start)
 | 
						|
{
 | 
						|
	u32 seq;
 | 
						|
 | 
						|
	smp_rmb();
 | 
						|
	seq = READ_ONCE(vc->seq);
 | 
						|
	return seq != start;
 | 
						|
}
 | 
						|
 | 
						|
static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
 | 
						|
{
 | 
						|
	struct vdso_clock *vc = vd->clock_data;
 | 
						|
 | 
						|
	/*
 | 
						|
	 * WRITE_ONCE() is required otherwise the compiler can validly tear
 | 
						|
	 * updates to vd[x].seq and it is possible that the value seen by the
 | 
						|
	 * reader is inconsistent.
 | 
						|
	 */
 | 
						|
	WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1);
 | 
						|
	WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1);
 | 
						|
	smp_wmb();
 | 
						|
}
 | 
						|
 | 
						|
static __always_inline void vdso_write_end(struct vdso_time_data *vd)
 | 
						|
{
 | 
						|
	struct vdso_clock *vc = vd->clock_data;
 | 
						|
 | 
						|
	smp_wmb();
 | 
						|
	/*
 | 
						|
	 * WRITE_ONCE() is required otherwise the compiler can validly tear
 | 
						|
	 * updates to vd[x].seq and it is possible that the value seen by the
 | 
						|
	 * reader is inconsistent.
 | 
						|
	 */
 | 
						|
	WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1);
 | 
						|
	WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1);
 | 
						|
}
 | 
						|
 | 
						|
#endif /* !__ASSEMBLY__ */
 | 
						|
 | 
						|
#endif /* __VDSO_HELPERS_H */
 |