Skip to content

Commit 886653e

Browse files
anna-marialxKAGA-KOKO
authored andcommitted
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: Anna-Maria Behnsen <[email protected]> Signed-off-by: Nam Cao <[email protected]> Signed-off-by: Thomas Weißschuh <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/all/[email protected]
1 parent 97a5a90 commit 886653e

File tree

10 files changed

+57
-54
lines changed

10 files changed

+57
-54
lines changed

arch/arm64/include/asm/vdso/compat_gettimeofday.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(
149149
* where __aarch64_get_vdso_u_time_data() is called, and then keep the
150150
* result in a register.
151151
*/
152-
asm volatile("mov %0, %1" : "=r"(ret) : "r"(vdso_u_time_data));
152+
asm volatile("mov %0, %1" : "=r"(ret) : "r"(&vdso_u_time_data));
153153

154154
return ret;
155155
}

arch/arm64/include/asm/vdso/vsyscall.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
static __always_inline
1616
void __arm64_update_vsyscall(struct vdso_time_data *vdata)
1717
{
18-
vdata[CS_HRES_COARSE].mask = VDSO_PRECISION_MASK;
19-
vdata[CS_RAW].mask = VDSO_PRECISION_MASK;
18+
vdata->clock_data[CS_HRES_COARSE].mask = VDSO_PRECISION_MASK;
19+
vdata->clock_data[CS_RAW].mask = VDSO_PRECISION_MASK;
2020
}
2121
#define __arch_update_vsyscall __arm64_update_vsyscall
2222

arch/s390/kernel/time.c

+3-8
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,10 @@ void __init time_early_init(void)
7979
{
8080
struct ptff_qto qto;
8181
struct ptff_qui qui;
82-
int cs;
8382

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

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

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

397392
/* Update LPAR offset. */
398393
if (ptff_query(PTFF_QTO) && ptff(&qto, sizeof(qto), PTFF_QTO) == 0)

include/asm-generic/vdso/vsyscall.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#ifndef __arch_get_vdso_u_time_data
1010
static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(void)
1111
{
12-
return vdso_u_time_data;
12+
return &vdso_u_time_data;
1313
}
1414
#endif
1515

include/vdso/datapage.h

+32-23
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,7 @@ struct vdso_timestamp {
6969
};
7070

7171
/**
72-
* struct vdso_time_data - vdso datapage representation
73-
* @arch_data: architecture specific data (optional, defaults
74-
* to an empty struct)
72+
* struct vdso_clock - vdso per clocksource datapage representation
7573
* @seq: timebase sequence counter
7674
* @clock_mode: clock mode
7775
* @cycle_last: timebase at clocksource init
@@ -81,17 +79,9 @@ struct vdso_timestamp {
8179
* @shift: clocksource shift
8280
* @basetime[clock_id]: basetime per clock_id
8381
* @offset[clock_id]: time namespace offset per clock_id
84-
* @tz_minuteswest: minutes west of Greenwich
85-
* @tz_dsttime: type of DST correction
86-
* @hrtimer_res: hrtimer resolution
87-
* @__unused: unused
8882
*
89-
* vdso_time_data will be accessed by 64 bit and compat code at the same time
90-
* so we should be careful before modifying this structure.
91-
*
92-
* The ordering of the struct members is optimized to have fast access to the
93-
* often required struct members which are related to CLOCK_REALTIME and
94-
* CLOCK_MONOTONIC. This information is stored in the first cache lines.
83+
* See also struct vdso_time_data for basic access and ordering information as
84+
* struct vdso_clock is used there.
9585
*
9686
* @basetime is used to store the base time for the system wide time getter
9787
* VVAR page.
@@ -104,9 +94,7 @@ struct vdso_timestamp {
10494
* For clocks which are not affected by time namespace adjustment the
10595
* offset must be zero.
10696
*/
107-
struct vdso_time_data {
108-
struct arch_vdso_time_data arch_data;
109-
97+
struct vdso_clock {
11098
u32 seq;
11199

112100
s32 clock_mode;
@@ -122,14 +110,35 @@ struct vdso_time_data {
122110
struct vdso_timestamp basetime[VDSO_BASES];
123111
struct timens_offset offset[VDSO_BASES];
124112
};
113+
};
125114

126-
s32 tz_minuteswest;
127-
s32 tz_dsttime;
128-
u32 hrtimer_res;
129-
u32 __unused;
130-
} ____cacheline_aligned;
115+
/**
116+
* struct vdso_time_data - vdso datapage representation
117+
* @arch_data: architecture specific data (optional, defaults
118+
* to an empty struct)
119+
* @clock_data: clocksource related data (array)
120+
* @tz_minuteswest: minutes west of Greenwich
121+
* @tz_dsttime: type of DST correction
122+
* @hrtimer_res: hrtimer resolution
123+
* @__unused: unused
124+
*
125+
* vdso_time_data will be accessed by 64 bit and compat code at the same time
126+
* so we should be careful before modifying this structure.
127+
*
128+
* The ordering of the struct members is optimized to have fast acces to the
129+
* often required struct members which are related to CLOCK_REALTIME and
130+
* CLOCK_MONOTONIC. This information is stored in the first cache lines.
131+
*/
132+
struct vdso_time_data {
133+
struct arch_vdso_time_data arch_data;
131134

132-
#define vdso_clock vdso_time_data
135+
struct vdso_clock clock_data[CS_BASES];
136+
137+
s32 tz_minuteswest;
138+
s32 tz_dsttime;
139+
u32 hrtimer_res;
140+
u32 __unused;
141+
} ____cacheline_aligned;
133142

134143
/**
135144
* struct vdso_rng_data - vdso RNG state information
@@ -151,7 +160,7 @@ struct vdso_rng_data {
151160
* relocation, and this is what we need.
152161
*/
153162
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
154-
extern struct vdso_time_data vdso_u_time_data[CS_BASES] __attribute__((visibility("hidden")));
163+
extern struct vdso_time_data vdso_u_time_data __attribute__((visibility("hidden")));
155164
extern struct vdso_rng_data vdso_u_rng_data __attribute__((visibility("hidden")));
156165
extern struct vdso_arch_data vdso_u_arch_data __attribute__((visibility("hidden")));
157166

include/vdso/helpers.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ static __always_inline u32 vdso_read_retry(const struct vdso_clock *vc,
3030

3131
static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
3232
{
33-
struct vdso_clock *vc = vd;
33+
struct vdso_clock *vc = vd->clock_data;
3434

3535
/*
3636
* WRITE_ONCE() is required otherwise the compiler can validly tear
@@ -44,7 +44,7 @@ static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
4444

4545
static __always_inline void vdso_write_end(struct vdso_time_data *vd)
4646
{
47-
struct vdso_clock *vc = vd;
47+
struct vdso_clock *vc = vd->clock_data;
4848

4949
smp_wmb();
5050
/*

kernel/time/namespace.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ static void timens_set_vvar_page(struct task_struct *task,
237237

238238
ns->frozen_offsets = true;
239239
vdata = page_address(ns->vvar_page);
240-
vc = vdata;
240+
vc = vdata->clock_data;
241241

242242
for (i = 0; i < CS_BASES; i++)
243243
timens_setup_vdso_clock_data(&vc[i], ns);

kernel/time/vsyscall.c

+5-6
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717

1818
static inline void update_vdso_time_data(struct vdso_time_data *vdata, struct timekeeper *tk)
1919
{
20+
struct vdso_clock *vc = vdata->clock_data;
2021
struct vdso_timestamp *vdso_ts;
21-
struct vdso_clock *vc = vdata;
2222
u64 nsec, sec;
2323

2424
vc[CS_HRES_COARSE].cycle_last = tk->tkr_mono.cycle_last;
@@ -78,8 +78,8 @@ static inline void update_vdso_time_data(struct vdso_time_data *vdata, struct ti
7878
void update_vsyscall(struct timekeeper *tk)
7979
{
8080
struct vdso_time_data *vdata = vdso_k_time_data;
81+
struct vdso_clock *vc = vdata->clock_data;
8182
struct vdso_timestamp *vdso_ts;
82-
struct vdso_clock *vc = vdata;
8383
s32 clock_mode;
8484
u64 nsec;
8585

@@ -109,9 +109,8 @@ void update_vsyscall(struct timekeeper *tk)
109109

110110
/*
111111
* Read without the seqlock held by clock_getres().
112-
* Note: No need to have a second copy.
113112
*/
114-
WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution);
113+
WRITE_ONCE(vdata->hrtimer_res, hrtimer_resolution);
115114

116115
/*
117116
* If the current clocksource is not VDSO capable, then spare the
@@ -131,8 +130,8 @@ void update_vsyscall_tz(void)
131130
{
132131
struct vdso_time_data *vdata = vdso_k_time_data;
133132

134-
vdata[CS_HRES_COARSE].tz_minuteswest = sys_tz.tz_minuteswest;
135-
vdata[CS_HRES_COARSE].tz_dsttime = sys_tz.tz_dsttime;
133+
vdata->tz_minuteswest = sys_tz.tz_minuteswest;
134+
vdata->tz_dsttime = sys_tz.tz_dsttime;
136135

137136
__arch_sync_vdso_time_data(vdata);
138137
}

lib/vdso/datastore.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
*/
1414
#ifdef CONFIG_HAVE_GENERIC_VDSO
1515
static union {
16-
struct vdso_time_data data[CS_BASES];
16+
struct vdso_time_data data;
1717
u8 page[PAGE_SIZE];
1818
} vdso_time_data_store __page_aligned_data;
19-
struct vdso_time_data *vdso_k_time_data = vdso_time_data_store.data;
19+
struct vdso_time_data *vdso_k_time_data = &vdso_time_data_store.data;
2020
static_assert(sizeof(vdso_time_data_store) == PAGE_SIZE);
2121
#endif /* CONFIG_HAVE_GENERIC_VDSO */
2222

lib/vdso/gettimeofday.c

+8-8
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
8787
{
8888
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
8989
const struct timens_offset *offs = &vcns->offset[clk];
90+
const struct vdso_clock *vc = vd->clock_data;
9091
const struct vdso_timestamp *vdso_ts;
91-
const struct vdso_clock *vc = vd;
9292
u64 cycles, ns;
9393
u32 seq;
9494
s64 sec;
@@ -199,8 +199,8 @@ int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock
199199
{
200200
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
201201
const struct timens_offset *offs = &vcns->offset[clk];
202+
const struct vdso_clock *vc = vd->clock_data;
202203
const struct vdso_timestamp *vdso_ts;
203-
const struct vdso_clock *vc = vd;
204204
u64 nsec;
205205
s64 sec;
206206
s32 seq;
@@ -265,7 +265,7 @@ static __always_inline int
265265
__cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
266266
struct __kernel_timespec *ts)
267267
{
268-
const struct vdso_clock *vc = vd;
268+
const struct vdso_clock *vc = vd->clock_data;
269269
u32 msk;
270270

271271
/* Check for negative values or invalid clocks */
@@ -337,7 +337,7 @@ static __maybe_unused int
337337
__cvdso_gettimeofday_data(const struct vdso_time_data *vd,
338338
struct __kernel_old_timeval *tv, struct timezone *tz)
339339
{
340-
const struct vdso_clock *vc = vd;
340+
const struct vdso_clock *vc = vd->clock_data;
341341

342342
if (likely(tv != NULL)) {
343343
struct __kernel_timespec ts;
@@ -371,13 +371,13 @@ __cvdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
371371
static __maybe_unused __kernel_old_time_t
372372
__cvdso_time_data(const struct vdso_time_data *vd, __kernel_old_time_t *time)
373373
{
374-
const struct vdso_clock *vc = vd;
374+
const struct vdso_clock *vc = vd->clock_data;
375375
__kernel_old_time_t t;
376376

377377
if (IS_ENABLED(CONFIG_TIME_NS) &&
378378
vc->clock_mode == VDSO_CLOCKMODE_TIMENS) {
379379
vd = __arch_get_vdso_u_timens_data(vd);
380-
vc = vd;
380+
vc = vd->clock_data;
381381
}
382382

383383
t = READ_ONCE(vc[CS_HRES_COARSE].basetime[CLOCK_REALTIME].sec);
@@ -399,7 +399,7 @@ static __maybe_unused
399399
int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock,
400400
struct __kernel_timespec *res)
401401
{
402-
const struct vdso_clock *vc = vd;
402+
const struct vdso_clock *vc = vd->clock_data;
403403
u32 msk;
404404
u64 ns;
405405

@@ -420,7 +420,7 @@ int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock
420420
/*
421421
* Preserves the behaviour of posix_get_hrtimer_res().
422422
*/
423-
ns = READ_ONCE(vd[CS_HRES_COARSE].hrtimer_res);
423+
ns = READ_ONCE(vd->hrtimer_res);
424424
} else if (msk & VDSO_COARSE) {
425425
/*
426426
* Preserves the behaviour of posix_get_coarse_res().

0 commit comments

Comments
 (0)