Skip to content

Commit d28ede8

Browse files
KAGA-KOKOjohnstultz-work
authored andcommitted
timekeeping: Create struct tk_read_base and use it in struct timekeeper
The members of the new struct are the required ones for the new NMI safe accessor to clcok monotonic. In order to reuse the existing timekeeping code and to make the update of the fast NMI safe timekeepers a simple memcpy use the struct for the timekeeper as well and convert all users. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ingo Molnar <mingo@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Signed-off-by: John Stultz <john.stultz@linaro.org>
1 parent 6d3aadf commit d28ede8

File tree

7 files changed

+158
-150
lines changed

7 files changed

+158
-150
lines changed

arch/arm64/kernel/vdso.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
211211
void update_vsyscall(struct timekeeper *tk)
212212
{
213213
struct timespec xtime_coarse;
214-
u32 use_syscall = strcmp(tk->clock->name, "arch_sys_counter");
214+
u32 use_syscall = strcmp(tk->tkr.clock->name, "arch_sys_counter");
215215

216216
++vdso_data->tb_seq_count;
217217
smp_wmb();
@@ -224,11 +224,11 @@ void update_vsyscall(struct timekeeper *tk)
224224
vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;
225225

226226
if (!use_syscall) {
227-
vdso_data->cs_cycle_last = tk->cycle_last;
227+
vdso_data->cs_cycle_last = tk->tkr.cycle_last;
228228
vdso_data->xtime_clock_sec = tk->xtime_sec;
229-
vdso_data->xtime_clock_nsec = tk->xtime_nsec;
230-
vdso_data->cs_mult = tk->mult;
231-
vdso_data->cs_shift = tk->shift;
229+
vdso_data->xtime_clock_nsec = tk->tkr.xtime_nsec;
230+
vdso_data->cs_mult = tk->tkr.mult;
231+
vdso_data->cs_shift = tk->tkr.shift;
232232
}
233233

234234
smp_wmb();

arch/s390/kernel/time.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -214,26 +214,26 @@ void update_vsyscall(struct timekeeper *tk)
214214
{
215215
u64 nsecps;
216216

217-
if (tk->clock != &clocksource_tod)
217+
if (tk->tkr.clock != &clocksource_tod)
218218
return;
219219

220220
/* Make userspace gettimeofday spin until we're done. */
221221
++vdso_data->tb_update_count;
222222
smp_wmb();
223-
vdso_data->xtime_tod_stamp = tk->cycle_last;
223+
vdso_data->xtime_tod_stamp = tk->tkr.cycle_last;
224224
vdso_data->xtime_clock_sec = tk->xtime_sec;
225-
vdso_data->xtime_clock_nsec = tk->xtime_nsec;
225+
vdso_data->xtime_clock_nsec = tk->tkr.xtime_nsec;
226226
vdso_data->wtom_clock_sec =
227227
tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
228-
vdso_data->wtom_clock_nsec = tk->xtime_nsec +
229-
+ ((u64) tk->wall_to_monotonic.tv_nsec << tk->shift);
230-
nsecps = (u64) NSEC_PER_SEC << tk->shift;
228+
vdso_data->wtom_clock_nsec = tk->tkr.xtime_nsec +
229+
+ ((u64) tk->wall_to_monotonic.tv_nsec << tk->tkr.shift);
230+
nsecps = (u64) NSEC_PER_SEC << tk->tkr.shift;
231231
while (vdso_data->wtom_clock_nsec >= nsecps) {
232232
vdso_data->wtom_clock_nsec -= nsecps;
233233
vdso_data->wtom_clock_sec++;
234234
}
235-
vdso_data->tk_mult = tk->mult;
236-
vdso_data->tk_shift = tk->shift;
235+
vdso_data->tk_mult = tk->tkr.mult;
236+
vdso_data->tk_shift = tk->tkr.shift;
237237
smp_wmb();
238238
++vdso_data->tb_update_count;
239239
}

arch/tile/kernel/time.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,21 +261,21 @@ void update_vsyscall_tz(void)
261261
void update_vsyscall(struct timekeeper *tk)
262262
{
263263
struct timespec *wtm = &tk->wall_to_monotonic;
264-
struct clocksource *clock = tk->clock;
264+
struct clocksource *clock = tk->tkr.clock;
265265

266266
if (clock != &cycle_counter_cs)
267267
return;
268268

269269
/* Userspace gettimeofday will spin while this value is odd. */
270270
++vdso_data->tb_update_count;
271271
smp_wmb();
272-
vdso_data->xtime_tod_stamp = tk->cycle_last;
272+
vdso_data->xtime_tod_stamp = tk->tkr.cycle_last;
273273
vdso_data->xtime_clock_sec = tk->xtime_sec;
274-
vdso_data->xtime_clock_nsec = tk->xtime_nsec;
274+
vdso_data->xtime_clock_nsec = tk->tkr.xtime_nsec;
275275
vdso_data->wtom_clock_sec = wtm->tv_sec;
276276
vdso_data->wtom_clock_nsec = wtm->tv_nsec;
277-
vdso_data->mult = tk->mult;
278-
vdso_data->shift = tk->shift;
277+
vdso_data->mult = tk->tkr.mult;
278+
vdso_data->shift = tk->tkr.shift;
279279
smp_wmb();
280280
++vdso_data->tb_update_count;
281281
}

arch/x86/kernel/vsyscall_gtod.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,29 +31,30 @@ void update_vsyscall(struct timekeeper *tk)
3131
gtod_write_begin(vdata);
3232

3333
/* copy vsyscall data */
34-
vdata->vclock_mode = tk->clock->archdata.vclock_mode;
35-
vdata->cycle_last = tk->cycle_last;
36-
vdata->mask = tk->clock->mask;
37-
vdata->mult = tk->mult;
38-
vdata->shift = tk->shift;
34+
vdata->vclock_mode = tk->tkr.clock->archdata.vclock_mode;
35+
vdata->cycle_last = tk->tkr.cycle_last;
36+
vdata->mask = tk->tkr.mask;
37+
vdata->mult = tk->tkr.mult;
38+
vdata->shift = tk->tkr.shift;
3939

4040
vdata->wall_time_sec = tk->xtime_sec;
41-
vdata->wall_time_snsec = tk->xtime_nsec;
41+
vdata->wall_time_snsec = tk->tkr.xtime_nsec;
4242

4343
vdata->monotonic_time_sec = tk->xtime_sec
4444
+ tk->wall_to_monotonic.tv_sec;
45-
vdata->monotonic_time_snsec = tk->xtime_nsec
45+
vdata->monotonic_time_snsec = tk->tkr.xtime_nsec
4646
+ ((u64)tk->wall_to_monotonic.tv_nsec
47-
<< tk->shift);
47+
<< tk->tkr.shift);
4848
while (vdata->monotonic_time_snsec >=
49-
(((u64)NSEC_PER_SEC) << tk->shift)) {
49+
(((u64)NSEC_PER_SEC) << tk->tkr.shift)) {
5050
vdata->monotonic_time_snsec -=
51-
((u64)NSEC_PER_SEC) << tk->shift;
51+
((u64)NSEC_PER_SEC) << tk->tkr.shift;
5252
vdata->monotonic_time_sec++;
5353
}
5454

5555
vdata->wall_time_coarse_sec = tk->xtime_sec;
56-
vdata->wall_time_coarse_nsec = (long)(tk->xtime_nsec >> tk->shift);
56+
vdata->wall_time_coarse_nsec = (long)(tk->tkr.xtime_nsec >>
57+
tk->tkr.shift);
5758

5859
vdata->monotonic_time_coarse_sec =
5960
vdata->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec;

arch/x86/kvm/x86.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -995,19 +995,19 @@ static void update_pvclock_gtod(struct timekeeper *tk)
995995
struct pvclock_gtod_data *vdata = &pvclock_gtod_data;
996996
u64 boot_ns;
997997

998-
boot_ns = ktime_to_ns(ktime_add(tk->base_mono, tk->offs_boot));
998+
boot_ns = ktime_to_ns(ktime_add(tk->tkr.base_mono, tk->offs_boot));
999999

10001000
write_seqcount_begin(&vdata->seq);
10011001

10021002
/* copy pvclock gtod data */
1003-
vdata->clock.vclock_mode = tk->clock->archdata.vclock_mode;
1004-
vdata->clock.cycle_last = tk->cycle_last;
1005-
vdata->clock.mask = tk->clock->mask;
1006-
vdata->clock.mult = tk->mult;
1007-
vdata->clock.shift = tk->shift;
1003+
vdata->clock.vclock_mode = tk->tkr.clock->archdata.vclock_mode;
1004+
vdata->clock.cycle_last = tk->tkr.cycle_last;
1005+
vdata->clock.mask = tk->tkr.mask;
1006+
vdata->clock.mult = tk->tkr.mult;
1007+
vdata->clock.shift = tk->tkr.shift;
10081008

10091009
vdata->boot_ns = boot_ns;
1010-
vdata->nsec_base = tk->xtime_nsec;
1010+
vdata->nsec_base = tk->tkr.xtime_nsec;
10111011

10121012
write_seqcount_end(&vdata->seq);
10131013
}

include/linux/timekeeper_internal.h

Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,80 +10,87 @@
1010
#include <linux/jiffies.h>
1111
#include <linux/time.h>
1212

13-
/*
14-
* Structure holding internal timekeeping values.
15-
*
16-
* Note: wall_to_monotonic is what we need to add to xtime (or xtime
17-
* corrected for sub jiffie times) to get to monotonic time.
18-
* Monotonic is pegged at zero at system boot time, so
19-
* wall_to_monotonic will be negative, however, we will ALWAYS keep
20-
* the tv_nsec part positive so we can use the usual normalization.
13+
/**
14+
* struct tk_read_base - base structure for timekeeping readout
15+
* @clock: Current clocksource used for timekeeping.
16+
* @read: Read function of @clock
17+
* @mask: Bitmask for two's complement subtraction of non 64bit clocks
18+
* @cycle_last: @clock cycle value at last update
19+
* @mult: NTP adjusted multiplier for scaled math conversion
20+
* @shift: Shift value for scaled math conversion
21+
* @xtime_nsec: Shifted (fractional) nano seconds offset for readout
22+
* @base_mono: ktime_t (nanoseconds) base time for readout
2123
*
22-
* wall_to_monotonic is moved after resume from suspend for the
23-
* monotonic time not to jump. To calculate the real boot time offset
24-
* we need to do offs_real - offs_boot.
24+
* This struct has size 56 byte on 64 bit. Together with a seqcount it
25+
* occupies a single 64byte cache line.
2526
*
26-
* - wall_to_monotonic is no longer the boot time, getboottime must be
27-
* used instead.
27+
* The struct is separate from struct timekeeper as it is also used
28+
* for a fast NMI safe accessor to clock monotonic.
2829
*/
29-
struct timekeeper {
30-
/* Current clocksource used for timekeeping. */
30+
struct tk_read_base {
3131
struct clocksource *clock;
32-
/* Read function of @clock */
3332
cycle_t (*read)(struct clocksource *cs);
34-
/* Bitmask for two's complement subtraction of non 64bit counters */
3533
cycle_t mask;
36-
/* Last cycle value */
3734
cycle_t cycle_last;
38-
/* NTP adjusted clock multiplier */
3935
u32 mult;
40-
/* The shift value of the current clocksource. */
4136
u32 shift;
42-
/* Clock shifted nano seconds */
4337
u64 xtime_nsec;
44-
45-
/* Monotonic base time */
4638
ktime_t base_mono;
39+
};
4740

48-
/* Current CLOCK_REALTIME time in seconds */
41+
/**
42+
* struct timekeeper - Structure holding internal timekeeping values.
43+
* @tkr: The readout base structure
44+
* @xtime_sec: Current CLOCK_REALTIME time in seconds
45+
* @wall_to_monotonic: CLOCK_REALTIME to CLOCK_MONOTONIC offset
46+
* @offs_real: Offset clock monotonic -> clock realtime
47+
* @offs_boot: Offset clock monotonic -> clock boottime
48+
* @offs_tai: Offset clock monotonic -> clock tai
49+
* @tai_offset: The current UTC to TAI offset in seconds
50+
* @base_raw: Monotonic raw base time in ktime_t format
51+
* @raw_time: Monotonic raw base time in timespec64 format
52+
* @cycle_interval: Number of clock cycles in one NTP interval
53+
* @xtime_interval: Number of clock shifted nano seconds in one NTP
54+
* interval.
55+
* @xtime_remainder: Shifted nano seconds left over when rounding
56+
* @cycle_interval
57+
* @raw_interval: Raw nano seconds accumulated per NTP interval.
58+
* @ntp_error: Difference between accumulated time and NTP time in ntp
59+
* shifted nano seconds.
60+
* @ntp_error_shift: Shift conversion between clock shifted nano seconds and
61+
* ntp shifted nano seconds.
62+
*
63+
* Note: For timespec(64) based interfaces wall_to_monotonic is what
64+
* we need to add to xtime (or xtime corrected for sub jiffie times)
65+
* to get to monotonic time. Monotonic is pegged at zero at system
66+
* boot time, so wall_to_monotonic will be negative, however, we will
67+
* ALWAYS keep the tv_nsec part positive so we can use the usual
68+
* normalization.
69+
*
70+
* wall_to_monotonic is moved after resume from suspend for the
71+
* monotonic time not to jump. We need to add total_sleep_time to
72+
* wall_to_monotonic to get the real boot based time offset.
73+
*
74+
* wall_to_monotonic is no longer the boot time, getboottime must be
75+
* used instead.
76+
*/
77+
struct timekeeper {
78+
struct tk_read_base tkr;
4979
u64 xtime_sec;
50-
/* CLOCK_REALTIME to CLOCK_MONOTONIC offset */
5180
struct timespec64 wall_to_monotonic;
52-
53-
/* Offset clock monotonic -> clock realtime */
5481
ktime_t offs_real;
55-
/* Offset clock monotonic -> clock boottime */
5682
ktime_t offs_boot;
57-
/* Offset clock monotonic -> clock tai */
5883
ktime_t offs_tai;
59-
60-
/* The current UTC to TAI offset in seconds */
6184
s32 tai_offset;
62-
63-
/* Monotonic raw base time */
6485
ktime_t base_raw;
65-
66-
/* The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. */
6786
struct timespec64 raw_time;
6887

69-
/* Number of clock cycles in one NTP interval. */
88+
/* The following members are for timekeeping internal use */
7089
cycle_t cycle_interval;
71-
/* Number of clock shifted nano seconds in one NTP interval. */
7290
u64 xtime_interval;
73-
/* shifted nano seconds left over when rounding cycle_interval */
7491
s64 xtime_remainder;
75-
/* Raw nano seconds accumulated per NTP interval. */
7692
u32 raw_interval;
77-
78-
/*
79-
* Difference between accumulated time and NTP time in ntp
80-
* shifted nano seconds.
81-
*/
8293
s64 ntp_error;
83-
/*
84-
* Shift conversion between clock shifted nano seconds and
85-
* ntp shifted nano seconds.
86-
*/
8794
u32 ntp_error_shift;
8895
};
8996

0 commit comments

Comments
 (0)