mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
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
This commit is contained in:
parent
a761a67f59
commit
1b267793f4
@ -2127,7 +2127,7 @@ static u64 logarithmic_accumulation(struct timekeeper *tk, u64 offset,
|
||||
* timekeeping_advance - Updates the timekeeper to the current time and
|
||||
* current NTP tick length
|
||||
*/
|
||||
static void timekeeping_advance(enum timekeeping_adv_mode mode)
|
||||
static bool timekeeping_advance(enum timekeeping_adv_mode mode)
|
||||
{
|
||||
struct timekeeper *real_tk = &tk_core.timekeeper;
|
||||
struct timekeeper *tk = &shadow_timekeeper;
|
||||
@ -2198,9 +2198,8 @@ static void timekeeping_advance(enum timekeeping_adv_mode mode)
|
||||
write_seqcount_end(&tk_core.seq);
|
||||
out:
|
||||
raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
|
||||
if (clock_set)
|
||||
/* Have to call _delayed version, since in irq context*/
|
||||
clock_was_set_delayed();
|
||||
|
||||
return !!clock_set;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2209,7 +2208,8 @@ out:
|
||||
*/
|
||||
void update_wall_time(void)
|
||||
{
|
||||
timekeeping_advance(TK_ADV_TICK);
|
||||
if (timekeeping_advance(TK_ADV_TICK))
|
||||
clock_was_set_delayed();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2389,8 +2389,9 @@ int do_adjtimex(struct __kernel_timex *txc)
|
||||
{
|
||||
struct timekeeper *tk = &tk_core.timekeeper;
|
||||
struct audit_ntp_data ad;
|
||||
unsigned long flags;
|
||||
bool clock_set = false;
|
||||
struct timespec64 ts;
|
||||
unsigned long flags;
|
||||
s32 orig_tai, tai;
|
||||
int ret;
|
||||
|
||||
@ -2425,6 +2426,7 @@ int do_adjtimex(struct __kernel_timex *txc)
|
||||
if (tai != orig_tai) {
|
||||
__timekeeping_set_tai_offset(tk, tai);
|
||||
timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET);
|
||||
clock_set = true;
|
||||
}
|
||||
tk_update_leap_state(tk);
|
||||
|
||||
@ -2435,9 +2437,9 @@ int do_adjtimex(struct __kernel_timex *txc)
|
||||
|
||||
/* Update the multiplier immediately if frequency was set directly */
|
||||
if (txc->modes & (ADJ_FREQUENCY | ADJ_TICK))
|
||||
timekeeping_advance(TK_ADV_FREQ);
|
||||
clock_set |= timekeeping_advance(TK_ADV_FREQ);
|
||||
|
||||
if (tai != orig_tai)
|
||||
if (clock_set)
|
||||
clock_was_set();
|
||||
|
||||
ntp_notify_cmos_timer();
|
||||
|
Loading…
Reference in New Issue
Block a user