Skip to content

Commit a56c41e

Browse files
committed
Merge tag 'timers-urgent-2020-01-27' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer fixes from Thomas Gleixner: "Two fixes for the generic VDSO code which missed 5.5: - Make the update to the coarse timekeeper unconditional. This is required because the coarse timekeeper interfaces in the VDSO do not depend on a VDSO capable clocksource. If the system does not have a VDSO capable clocksource and the update is depending on the VDSO capable clocksource, the coarse VDSO interfaces would operate on stale data forever. - Invert the logic of __arch_update_vdso_data() to avoid further head scratching. Tripped over this several times while analyzing the update problem above" * tag 'timers-urgent-2020-01-27' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: lib/vdso: Update coarse timekeeper unconditionally lib/vdso: Make __arch_update_vdso_data() logic understandable
2 parents b1dba24 + 9f24c54 commit a56c41e

File tree

3 files changed

+21
-24
lines changed

3 files changed

+21
-24
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ struct vdso_data *__arm_get_k_vdso_data(void)
3434
#define __arch_get_k_vdso_data __arm_get_k_vdso_data
3535

3636
static __always_inline
37-
int __arm_update_vdso_data(void)
37+
bool __arm_update_vdso_data(void)
3838
{
39-
return !cntvct_ok;
39+
return cntvct_ok;
4040
}
4141
#define __arch_update_vdso_data __arm_update_vdso_data
4242

include/asm-generic/vdso/vsyscall.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ static __always_inline struct vdso_data *__arch_get_k_vdso_data(void)
1212
#endif /* __arch_get_k_vdso_data */
1313

1414
#ifndef __arch_update_vdso_data
15-
static __always_inline int __arch_update_vdso_data(void)
15+
static __always_inline bool __arch_update_vdso_data(void)
1616
{
17-
return 0;
17+
return true;
1818
}
1919
#endif /* __arch_update_vdso_data */
2020

kernel/time/vsyscall.c

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@ static inline void update_vdso_data(struct vdso_data *vdata,
2828
vdata[CS_RAW].mult = tk->tkr_raw.mult;
2929
vdata[CS_RAW].shift = tk->tkr_raw.shift;
3030

31-
/* CLOCK_REALTIME */
32-
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
33-
vdso_ts->sec = tk->xtime_sec;
34-
vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
35-
3631
/* CLOCK_MONOTONIC */
3732
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
3833
vdso_ts->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
@@ -70,12 +65,6 @@ static inline void update_vdso_data(struct vdso_data *vdata,
7065
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_TAI];
7166
vdso_ts->sec = tk->xtime_sec + (s64)tk->tai_offset;
7267
vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
73-
74-
/*
75-
* Read without the seqlock held by clock_getres().
76-
* Note: No need to have a second copy.
77-
*/
78-
WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution);
7968
}
8069

8170
void update_vsyscall(struct timekeeper *tk)
@@ -84,20 +73,17 @@ void update_vsyscall(struct timekeeper *tk)
8473
struct vdso_timestamp *vdso_ts;
8574
u64 nsec;
8675

87-
if (__arch_update_vdso_data()) {
88-
/*
89-
* Some architectures might want to skip the update of the
90-
* data page.
91-
*/
92-
return;
93-
}
94-
9576
/* copy vsyscall data */
9677
vdso_write_begin(vdata);
9778

9879
vdata[CS_HRES_COARSE].clock_mode = __arch_get_clock_mode(tk);
9980
vdata[CS_RAW].clock_mode = __arch_get_clock_mode(tk);
10081

82+
/* CLOCK_REALTIME also required for time() */
83+
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
84+
vdso_ts->sec = tk->xtime_sec;
85+
vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
86+
10187
/* CLOCK_REALTIME_COARSE */
10288
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME_COARSE];
10389
vdso_ts->sec = tk->xtime_sec;
@@ -110,7 +96,18 @@ void update_vsyscall(struct timekeeper *tk)
11096
nsec = nsec + tk->wall_to_monotonic.tv_nsec;
11197
vdso_ts->sec += __iter_div_u64_rem(nsec, NSEC_PER_SEC, &vdso_ts->nsec);
11298

113-
update_vdso_data(vdata, tk);
99+
/*
100+
* Read without the seqlock held by clock_getres().
101+
* Note: No need to have a second copy.
102+
*/
103+
WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution);
104+
105+
/*
106+
* Architectures can opt out of updating the high resolution part
107+
* of the VDSO.
108+
*/
109+
if (__arch_update_vdso_data())
110+
update_vdso_data(vdata, tk);
114111

115112
__arch_update_vsyscall(vdata, tk);
116113

0 commit comments

Comments
 (0)