Skip to content

Commit 1b26779

Browse files
committed
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent a761a67 commit 1b26779

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

kernel/time/timekeeping.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2127,7 +2127,7 @@ static u64 logarithmic_accumulation(struct timekeeper *tk, u64 offset,
21272127
* timekeeping_advance - Updates the timekeeper to the current time and
21282128
* current NTP tick length
21292129
*/
2130-
static void timekeeping_advance(enum timekeeping_adv_mode mode)
2130+
static bool timekeeping_advance(enum timekeeping_adv_mode mode)
21312131
{
21322132
struct timekeeper *real_tk = &tk_core.timekeeper;
21332133
struct timekeeper *tk = &shadow_timekeeper;
@@ -2198,9 +2198,8 @@ static void timekeeping_advance(enum timekeeping_adv_mode mode)
21982198
write_seqcount_end(&tk_core.seq);
21992199
out:
22002200
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;
22042203
}
22052204

22062205
/**
@@ -2209,7 +2208,8 @@ static void timekeeping_advance(enum timekeeping_adv_mode mode)
22092208
*/
22102209
void update_wall_time(void)
22112210
{
2212-
timekeeping_advance(TK_ADV_TICK);
2211+
if (timekeeping_advance(TK_ADV_TICK))
2212+
clock_was_set_delayed();
22132213
}
22142214

22152215
/**
@@ -2389,8 +2389,9 @@ int do_adjtimex(struct __kernel_timex *txc)
23892389
{
23902390
struct timekeeper *tk = &tk_core.timekeeper;
23912391
struct audit_ntp_data ad;
2392-
unsigned long flags;
2392+
bool clock_set = false;
23932393
struct timespec64 ts;
2394+
unsigned long flags;
23942395
s32 orig_tai, tai;
23952396
int ret;
23962397

@@ -2425,6 +2426,7 @@ int do_adjtimex(struct __kernel_timex *txc)
24252426
if (tai != orig_tai) {
24262427
__timekeeping_set_tai_offset(tk, tai);
24272428
timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET);
2429+
clock_set = true;
24282430
}
24292431
tk_update_leap_state(tk);
24302432

@@ -2435,9 +2437,9 @@ int do_adjtimex(struct __kernel_timex *txc)
24352437

24362438
/* Update the multiplier immediately if frequency was set directly */
24372439
if (txc->modes & (ADJ_FREQUENCY | ADJ_TICK))
2438-
timekeeping_advance(TK_ADV_FREQ);
2440+
clock_set |= timekeeping_advance(TK_ADV_FREQ);
24392441

2440-
if (tai != orig_tai)
2442+
if (clock_set)
24412443
clock_was_set();
24422444

24432445
ntp_notify_cmos_timer();

0 commit comments

Comments
 (0)