Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

time/timekeeping: Avoid invoking clock_was_set() twice

do_adjtimex() might end up scheduling a delayed clock_was_set() via
timekeeping_advance() and then invoke clock_was_set() directly which is
pointless.

Make timekeeping_advance() return whether an invocation of clock_was_set()
is required and handle it at the call sites which allows do_adjtimex() to
issue a single direct call if required.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20210713135158.580966888@linutronix.de

+10 -8
+10 -8
kernel/time/timekeeping.c
··· 2127 2127 * timekeeping_advance - Updates the timekeeper to the current time and 2128 2128 * current NTP tick length 2129 2129 */ 2130 - static void timekeeping_advance(enum timekeeping_adv_mode mode) 2130 + static bool timekeeping_advance(enum timekeeping_adv_mode mode) 2131 2131 { 2132 2132 struct timekeeper *real_tk = &tk_core.timekeeper; 2133 2133 struct timekeeper *tk = &shadow_timekeeper; ··· 2198 2198 write_seqcount_end(&tk_core.seq); 2199 2199 out: 2200 2200 raw_spin_unlock_irqrestore(&timekeeper_lock, flags); 2201 - if (clock_set) 2202 - /* Have to call _delayed version, since in irq context*/ 2203 - clock_was_set_delayed(); 2201 + 2202 + return !!clock_set; 2204 2203 } 2205 2204 2206 2205 /** ··· 2208 2209 */ 2209 2210 void update_wall_time(void) 2210 2211 { 2211 - timekeeping_advance(TK_ADV_TICK); 2212 + if (timekeeping_advance(TK_ADV_TICK)) 2213 + clock_was_set_delayed(); 2212 2214 } 2213 2215 2214 2216 /** ··· 2389 2389 { 2390 2390 struct timekeeper *tk = &tk_core.timekeeper; 2391 2391 struct audit_ntp_data ad; 2392 - unsigned long flags; 2392 + bool clock_set = false; 2393 2393 struct timespec64 ts; 2394 + unsigned long flags; 2394 2395 s32 orig_tai, tai; 2395 2396 int ret; 2396 2397 ··· 2426 2425 if (tai != orig_tai) { 2427 2426 __timekeeping_set_tai_offset(tk, tai); 2428 2427 timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET); 2428 + clock_set = true; 2429 2429 } 2430 2430 tk_update_leap_state(tk); 2431 2431 ··· 2437 2435 2438 2436 /* Update the multiplier immediately if frequency was set directly */ 2439 2437 if (txc->modes & (ADJ_FREQUENCY | ADJ_TICK)) 2440 - timekeeping_advance(TK_ADV_FREQ); 2438 + clock_set |= timekeeping_advance(TK_ADV_FREQ); 2441 2439 2442 - if (tai != orig_tai) 2440 + if (clock_set) 2443 2441 clock_was_set(); 2444 2442 2445 2443 ntp_notify_cmos_timer();