Skip to content

Commit 1001d0a

Browse files
KAGA-KOKOIngo Molnar
authored andcommitted
timekeeping: update xtime_cache when time(zone) changes
xtime_cache needs to be updated whenever xtime and or wall_to_monotic are changed. Otherwise users of xtime_cache might see a stale (and in the case of timezone changes utterly wrong) value until the next update happens. Fixup the obvious places, which miss this update. Signed-off-by: Thomas Gleixner <[email protected]> Acked-by: John Stultz <[email protected]> Tested-by: Dhaval Giani <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
1 parent 3588a08 commit 1001d0a

File tree

3 files changed

+6
-2
lines changed

3 files changed

+6
-2
lines changed

include/linux/time.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ extern void monotonic_to_bootbased(struct timespec *ts);
122122
extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
123123
extern int timekeeping_is_continuous(void);
124124
extern void update_wall_time(void);
125+
extern void update_xtime_cache(u64 nsec);
125126

126127
/**
127128
* timespec_to_ns - Convert timespec to nanoseconds

kernel/time.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ static inline void warp_clock(void)
129129
write_seqlock_irq(&xtime_lock);
130130
wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60;
131131
xtime.tv_sec += sys_tz.tz_minuteswest * 60;
132+
update_xtime_cache(0);
132133
write_sequnlock_irq(&xtime_lock);
133134
clock_was_set();
134135
}

kernel/time/timekeeping.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
4747
static unsigned long total_sleep_time; /* seconds */
4848

4949
static struct timespec xtime_cache __attribute__ ((aligned (16)));
50-
static inline void update_xtime_cache(u64 nsec)
50+
void update_xtime_cache(u64 nsec)
5151
{
5252
xtime_cache = xtime;
5353
timespec_add_ns(&xtime_cache, nsec);
@@ -145,6 +145,7 @@ int do_settimeofday(struct timespec *tv)
145145

146146
set_normalized_timespec(&xtime, sec, nsec);
147147
set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
148+
update_xtime_cache(0);
148149

149150
clock->error = 0;
150151
ntp_clear();
@@ -252,8 +253,8 @@ void __init timekeeping_init(void)
252253
xtime.tv_nsec = 0;
253254
set_normalized_timespec(&wall_to_monotonic,
254255
-xtime.tv_sec, -xtime.tv_nsec);
256+
update_xtime_cache(0);
255257
total_sleep_time = 0;
256-
257258
write_sequnlock_irqrestore(&xtime_lock, flags);
258259
}
259260

@@ -290,6 +291,7 @@ static int timekeeping_resume(struct sys_device *dev)
290291
}
291292
/* Make sure that we have the correct xtime reference */
292293
timespec_add_ns(&xtime, timekeeping_suspend_nsecs);
294+
update_xtime_cache(0);
293295
/* re-base the last cycle value */
294296
clock->cycle_last = clocksource_read(clock);
295297
clock->error = 0;

0 commit comments

Comments
 (0)