Skip to content

Commit a3ed0e4

Browse files
committed
Revert: Unify CLOCK_MONOTONIC and CLOCK_BOOTTIME
Revert commits 92af4dc ("tracing: Unify the "boot" and "mono" tracing clocks") 127bfa5 ("hrtimer: Unify MONOTONIC and BOOTTIME clock behavior") 7250a40 ("posix-timers: Unify MONOTONIC and BOOTTIME clock behavior") d6c7270 ("timekeeping: Remove boot time specific code") f2d6fdb ("Input: Evdev - unify MONOTONIC and BOOTTIME clock behavior") d6ed449 ("timekeeping: Make the MONOTONIC clock behave like the BOOTTIME clock") 7219932 ("timekeeping: Add the new CLOCK_MONOTONIC_ACTIVE clock") As stated in the pull request for the unification of CLOCK_MONOTONIC and CLOCK_BOOTTIME, it was clear that we might have to revert the change. As reported by several folks systemd and other applications rely on the documented behaviour of CLOCK_MONOTONIC on Linux and break with the above changes. After resume daemons time out and other timeout related issues are observed. Rafael compiled this list: * systemd kills daemons on resume, after >WatchdogSec seconds of suspending (Genki Sky). [Verified that that's because systemd uses CLOCK_MONOTONIC and expects it to not include the suspend time.] * systemd-journald misbehaves after resume: systemd-journald[7266]: File /var/log/journal/016627c3c4784cd4812d4b7e96a34226/system.journal corrupted or uncleanly shut down, renaming and replacing. (Mike Galbraith). * NetworkManager reports "networking disabled" and networking is broken after resume 50% of the time (Pavel). [May be because of systemd.] * MATE desktop dims the display and starts the screensaver right after system resume (Pavel). * Full system hang during resume (me). [May be due to systemd or NM or both.] That happens on debian and open suse systems. It's sad, that these problems were neither catched in -next nor by those folks who expressed interest in this change. Reported-by: Rafael J. Wysocki <[email protected]> Reported-by: Genki Sky <[email protected]>, Reported-by: Pavel Machek <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Cc: Dmitry Torokhov <[email protected]> Cc: John Stultz <[email protected]> Cc: Jonathan Corbet <[email protected]> Cc: Kevin Easton <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Mark Salyzyn <[email protected]> Cc: Michael Kerrisk <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Petr Mladek <[email protected]> Cc: Prarit Bhargava <[email protected]> Cc: Sergey Senozhatsky <[email protected]> Cc: Steven Rostedt <[email protected]>
1 parent 1f71add commit a3ed0e4

File tree

15 files changed

+114
-104
lines changed

15 files changed

+114
-104
lines changed

Documentation/trace/ftrace.rst

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,17 @@ of ftrace. Here is a list of some of the key files:
461461
and ticks at the same rate as the hardware clocksource.
462462

463463
boot:
464-
Same as mono. Used to be a separate clock which accounted
465-
for the time spent in suspend while CLOCK_MONOTONIC did
466-
not.
464+
This is the boot clock (CLOCK_BOOTTIME) and is based on the
465+
fast monotonic clock, but also accounts for time spent in
466+
suspend. Since the clock access is designed for use in
467+
tracing in the suspend path, some side effects are possible
468+
if clock is accessed after the suspend time is accounted before
469+
the fast mono clock is updated. In this case, the clock update
470+
appears to happen slightly sooner than it normally would have.
471+
Also on 32-bit systems, it's possible that the 64-bit boot offset
472+
sees a partial update. These effects are rare and post
473+
processing should be able to handle them. See comments in the
474+
ktime_get_boot_fast_ns() function for more information.
467475

468476
To set a clock, simply echo the clock name into this file::
469477

drivers/input/evdev.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
enum evdev_clock_type {
3232
EV_CLK_REAL = 0,
3333
EV_CLK_MONO,
34+
EV_CLK_BOOT,
3435
EV_CLK_MAX
3536
};
3637

@@ -197,10 +198,12 @@ static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
197198
case CLOCK_REALTIME:
198199
clk_type = EV_CLK_REAL;
199200
break;
200-
case CLOCK_BOOTTIME:
201201
case CLOCK_MONOTONIC:
202202
clk_type = EV_CLK_MONO;
203203
break;
204+
case CLOCK_BOOTTIME:
205+
clk_type = EV_CLK_BOOT;
206+
break;
204207
default:
205208
return -EINVAL;
206209
}
@@ -311,6 +314,8 @@ static void evdev_events(struct input_handle *handle,
311314

312315
ev_time[EV_CLK_MONO] = ktime_get();
313316
ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]);
317+
ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO],
318+
TK_OFFS_BOOT);
314319

315320
rcu_read_lock();
316321

include/linux/hrtimer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,11 @@ struct hrtimer_clock_base {
161161
enum hrtimer_base_type {
162162
HRTIMER_BASE_MONOTONIC,
163163
HRTIMER_BASE_REALTIME,
164+
HRTIMER_BASE_BOOTTIME,
164165
HRTIMER_BASE_TAI,
165166
HRTIMER_BASE_MONOTONIC_SOFT,
166167
HRTIMER_BASE_REALTIME_SOFT,
168+
HRTIMER_BASE_BOOTTIME_SOFT,
167169
HRTIMER_BASE_TAI_SOFT,
168170
HRTIMER_MAX_CLOCK_BASES,
169171
};

include/linux/timekeeper_internal.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ struct tk_read_base {
5252
* @offs_real: Offset clock monotonic -> clock realtime
5353
* @offs_boot: Offset clock monotonic -> clock boottime
5454
* @offs_tai: Offset clock monotonic -> clock tai
55-
* @time_suspended: Accumulated suspend time
5655
* @tai_offset: The current UTC to TAI offset in seconds
5756
* @clock_was_set_seq: The sequence number of clock was set events
5857
* @cs_was_changed_seq: The sequence number of clocksource change events
@@ -95,7 +94,6 @@ struct timekeeper {
9594
ktime_t offs_real;
9695
ktime_t offs_boot;
9796
ktime_t offs_tai;
98-
ktime_t time_suspended;
9997
s32 tai_offset;
10098
unsigned int clock_was_set_seq;
10199
u8 cs_was_changed_seq;

include/linux/timekeeping.h

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,20 @@ extern void ktime_get_ts64(struct timespec64 *ts);
3333
extern time64_t ktime_get_seconds(void);
3434
extern time64_t __ktime_get_real_seconds(void);
3535
extern time64_t ktime_get_real_seconds(void);
36-
extern void ktime_get_active_ts64(struct timespec64 *ts);
3736

3837
extern int __getnstimeofday64(struct timespec64 *tv);
3938
extern void getnstimeofday64(struct timespec64 *tv);
4039
extern void getboottime64(struct timespec64 *ts);
4140

42-
#define ktime_get_real_ts64(ts) getnstimeofday64(ts)
43-
44-
/* Clock BOOTTIME compatibility wrappers */
45-
static inline void get_monotonic_boottime64(struct timespec64 *ts)
46-
{
47-
ktime_get_ts64(ts);
48-
}
41+
#define ktime_get_real_ts64(ts) getnstimeofday64(ts)
4942

5043
/*
5144
* ktime_t based interfaces
5245
*/
46+
5347
enum tk_offsets {
5448
TK_OFFS_REAL,
49+
TK_OFFS_BOOT,
5550
TK_OFFS_TAI,
5651
TK_OFFS_MAX,
5752
};
@@ -62,10 +57,6 @@ extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
6257
extern ktime_t ktime_get_raw(void);
6358
extern u32 ktime_get_resolution_ns(void);
6459

65-
/* Clock BOOTTIME compatibility wrappers */
66-
static inline ktime_t ktime_get_boottime(void) { return ktime_get(); }
67-
static inline u64 ktime_get_boot_ns(void) { return ktime_get(); }
68-
6960
/**
7061
* ktime_get_real - get the real (wall-) time in ktime_t format
7162
*/
@@ -74,6 +65,17 @@ static inline ktime_t ktime_get_real(void)
7465
return ktime_get_with_offset(TK_OFFS_REAL);
7566
}
7667

68+
/**
69+
* ktime_get_boottime - Returns monotonic time since boot in ktime_t format
70+
*
71+
* This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
72+
* time spent in suspend.
73+
*/
74+
static inline ktime_t ktime_get_boottime(void)
75+
{
76+
return ktime_get_with_offset(TK_OFFS_BOOT);
77+
}
78+
7779
/**
7880
* ktime_get_clocktai - Returns the TAI time of day in ktime_t format
7981
*/
@@ -100,6 +102,11 @@ static inline u64 ktime_get_real_ns(void)
100102
return ktime_to_ns(ktime_get_real());
101103
}
102104

105+
static inline u64 ktime_get_boot_ns(void)
106+
{
107+
return ktime_to_ns(ktime_get_boottime());
108+
}
109+
103110
static inline u64 ktime_get_tai_ns(void)
104111
{
105112
return ktime_to_ns(ktime_get_clocktai());
@@ -112,11 +119,17 @@ static inline u64 ktime_get_raw_ns(void)
112119

113120
extern u64 ktime_get_mono_fast_ns(void);
114121
extern u64 ktime_get_raw_fast_ns(void);
122+
extern u64 ktime_get_boot_fast_ns(void);
115123
extern u64 ktime_get_real_fast_ns(void);
116124

117125
/*
118126
* timespec64 interfaces utilizing the ktime based ones
119127
*/
128+
static inline void get_monotonic_boottime64(struct timespec64 *ts)
129+
{
130+
*ts = ktime_to_timespec64(ktime_get_boottime());
131+
}
132+
120133
static inline void timekeeping_clocktai64(struct timespec64 *ts)
121134
{
122135
*ts = ktime_to_timespec64(ktime_get_clocktai());

include/uapi/linux/time.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ struct __kernel_old_timeval {
7373
*/
7474
#define CLOCK_SGI_CYCLE 10
7575
#define CLOCK_TAI 11
76-
#define CLOCK_MONOTONIC_ACTIVE 12
7776

7877
#define MAX_CLOCKS 16
7978
#define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC)

kernel/time/hrtimer.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
9090
.clockid = CLOCK_REALTIME,
9191
.get_time = &ktime_get_real,
9292
},
93+
{
94+
.index = HRTIMER_BASE_BOOTTIME,
95+
.clockid = CLOCK_BOOTTIME,
96+
.get_time = &ktime_get_boottime,
97+
},
9398
{
9499
.index = HRTIMER_BASE_TAI,
95100
.clockid = CLOCK_TAI,
@@ -105,6 +110,11 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
105110
.clockid = CLOCK_REALTIME,
106111
.get_time = &ktime_get_real,
107112
},
113+
{
114+
.index = HRTIMER_BASE_BOOTTIME_SOFT,
115+
.clockid = CLOCK_BOOTTIME,
116+
.get_time = &ktime_get_boottime,
117+
},
108118
{
109119
.index = HRTIMER_BASE_TAI_SOFT,
110120
.clockid = CLOCK_TAI,
@@ -119,7 +129,7 @@ static const int hrtimer_clock_to_base_table[MAX_CLOCKS] = {
119129

120130
[CLOCK_REALTIME] = HRTIMER_BASE_REALTIME,
121131
[CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC,
122-
[CLOCK_BOOTTIME] = HRTIMER_BASE_MONOTONIC,
132+
[CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME,
123133
[CLOCK_TAI] = HRTIMER_BASE_TAI,
124134
};
125135

@@ -571,12 +581,14 @@ __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base, unsigned int active_
571581
static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base)
572582
{
573583
ktime_t *offs_real = &base->clock_base[HRTIMER_BASE_REALTIME].offset;
584+
ktime_t *offs_boot = &base->clock_base[HRTIMER_BASE_BOOTTIME].offset;
574585
ktime_t *offs_tai = &base->clock_base[HRTIMER_BASE_TAI].offset;
575586

576587
ktime_t now = ktime_get_update_offsets_now(&base->clock_was_set_seq,
577-
offs_real, offs_tai);
588+
offs_real, offs_boot, offs_tai);
578589

579590
base->clock_base[HRTIMER_BASE_REALTIME_SOFT].offset = *offs_real;
591+
base->clock_base[HRTIMER_BASE_BOOTTIME_SOFT].offset = *offs_boot;
580592
base->clock_base[HRTIMER_BASE_TAI_SOFT].offset = *offs_tai;
581593

582594
return now;

kernel/time/posix-stubs.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp)
8383
case CLOCK_BOOTTIME:
8484
get_monotonic_boottime64(tp);
8585
break;
86-
case CLOCK_MONOTONIC_ACTIVE:
87-
ktime_get_active_ts64(tp);
8886
default:
8987
return -EINVAL;
9088
}

kernel/time/posix-timers.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -252,16 +252,15 @@ static int posix_get_coarse_res(const clockid_t which_clock, struct timespec64 *
252252
return 0;
253253
}
254254

255-
static int posix_get_tai(clockid_t which_clock, struct timespec64 *tp)
255+
static int posix_get_boottime(const clockid_t which_clock, struct timespec64 *tp)
256256
{
257-
timekeeping_clocktai64(tp);
257+
get_monotonic_boottime64(tp);
258258
return 0;
259259
}
260260

261-
static int posix_get_monotonic_active(clockid_t which_clock,
262-
struct timespec64 *tp)
261+
static int posix_get_tai(clockid_t which_clock, struct timespec64 *tp)
263262
{
264-
ktime_get_active_ts64(tp);
263+
timekeeping_clocktai64(tp);
265264
return 0;
266265
}
267266

@@ -1317,9 +1316,19 @@ static const struct k_clock clock_tai = {
13171316
.timer_arm = common_hrtimer_arm,
13181317
};
13191318

1320-
static const struct k_clock clock_monotonic_active = {
1319+
static const struct k_clock clock_boottime = {
13211320
.clock_getres = posix_get_hrtimer_res,
1322-
.clock_get = posix_get_monotonic_active,
1321+
.clock_get = posix_get_boottime,
1322+
.nsleep = common_nsleep,
1323+
.timer_create = common_timer_create,
1324+
.timer_set = common_timer_set,
1325+
.timer_get = common_timer_get,
1326+
.timer_del = common_timer_del,
1327+
.timer_rearm = common_hrtimer_rearm,
1328+
.timer_forward = common_hrtimer_forward,
1329+
.timer_remaining = common_hrtimer_remaining,
1330+
.timer_try_to_cancel = common_hrtimer_try_to_cancel,
1331+
.timer_arm = common_hrtimer_arm,
13231332
};
13241333

13251334
static const struct k_clock * const posix_clocks[] = {
@@ -1330,11 +1339,10 @@ static const struct k_clock * const posix_clocks[] = {
13301339
[CLOCK_MONOTONIC_RAW] = &clock_monotonic_raw,
13311340
[CLOCK_REALTIME_COARSE] = &clock_realtime_coarse,
13321341
[CLOCK_MONOTONIC_COARSE] = &clock_monotonic_coarse,
1333-
[CLOCK_BOOTTIME] = &clock_monotonic,
1342+
[CLOCK_BOOTTIME] = &clock_boottime,
13341343
[CLOCK_REALTIME_ALARM] = &alarm_clock,
13351344
[CLOCK_BOOTTIME_ALARM] = &alarm_clock,
13361345
[CLOCK_TAI] = &clock_tai,
1337-
[CLOCK_MONOTONIC_ACTIVE] = &clock_monotonic_active,
13381346
};
13391347

13401348
static const struct k_clock *clockid_to_kclock(const clockid_t id)

kernel/time/tick-common.c

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -419,19 +419,6 @@ void tick_suspend_local(void)
419419
clockevents_shutdown(td->evtdev);
420420
}
421421

422-
static void tick_forward_next_period(void)
423-
{
424-
ktime_t delta, now = ktime_get();
425-
u64 n;
426-
427-
delta = ktime_sub(now, tick_next_period);
428-
n = ktime_divns(delta, tick_period);
429-
tick_next_period += n * tick_period;
430-
if (tick_next_period < now)
431-
tick_next_period += tick_period;
432-
tick_sched_forward_next_period();
433-
}
434-
435422
/**
436423
* tick_resume_local - Resume the local tick device
437424
*
@@ -444,8 +431,6 @@ void tick_resume_local(void)
444431
struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
445432
bool broadcast = tick_resume_check_broadcast();
446433

447-
tick_forward_next_period();
448-
449434
clockevents_tick_resume(td->evtdev);
450435
if (!broadcast) {
451436
if (td->mode == TICKDEV_MODE_PERIODIC)

kernel/time/tick-internal.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,6 @@ static inline void tick_check_oneshot_broadcast_this_cpu(void) { }
141141
static inline bool tick_broadcast_oneshot_available(void) { return tick_oneshot_possible(); }
142142
#endif /* !(BROADCAST && ONESHOT) */
143143

144-
#if defined(CONFIG_NO_HZ_COMMON) || defined(CONFIG_HIGH_RES_TIMERS)
145-
extern void tick_sched_forward_next_period(void);
146-
#else
147-
static inline void tick_sched_forward_next_period(void) { }
148-
#endif
149-
150144
/* NO_HZ_FULL internal */
151145
#ifdef CONFIG_NO_HZ_FULL
152146
extern void tick_nohz_init(void);

kernel/time/tick-sched.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,6 @@ struct tick_sched *tick_get_tick_sched(int cpu)
5151
*/
5252
static ktime_t last_jiffies_update;
5353

54-
/*
55-
* Called after resume. Make sure that jiffies are not fast forwarded due to
56-
* clock monotonic being forwarded by the suspended time.
57-
*/
58-
void tick_sched_forward_next_period(void)
59-
{
60-
last_jiffies_update = tick_next_period;
61-
}
62-
6354
/*
6455
* Must be called with interrupts disabled !
6556
*/

0 commit comments

Comments
 (0)