Skip to content

Commit 47a1b79

Browse files
tick/timekeeping: Call update_wall_time outside the jiffies lock
Since the xtime lock was split into the timekeeping lock and the jiffies lock, we no longer need to call update_wall_time() while holding the jiffies lock. Thus, this patch splits update_wall_time() out from do_timer(). This allows us to get away from calling clock_was_set_delayed() in update_wall_time() and instead use the standard clock_was_set() call that previously would deadlock, as it causes the jiffies lock to be acquired. Cc: Sasha Levin <sasha.levin@oracle.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Prarit Bhargava <prarit@redhat.com> Cc: Richard Cochran <richardcochran@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Signed-off-by: John Stultz <john.stultz@linaro.org>
1 parent 6fdda9a commit 47a1b79

File tree

4 files changed

+7
-15
lines changed

4 files changed

+7
-15
lines changed

kernel/time/tick-common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ static void tick_periodic(int cpu)
7070

7171
do_timer(1);
7272
write_sequnlock(&jiffies_lock);
73+
update_wall_time();
7374
}
7475

7576
update_process_times(user_mode(get_irq_regs()));

kernel/time/tick-internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,4 @@ static inline int tick_device_is_functional(struct clock_event_device *dev)
155155
#endif
156156

157157
extern void do_timer(unsigned long ticks);
158+
extern void update_wall_time(void);

kernel/time/tick-sched.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ static void tick_do_update_jiffies64(ktime_t now)
8686
tick_next_period = ktime_add(last_jiffies_update, tick_period);
8787
}
8888
write_sequnlock(&jiffies_lock);
89+
update_wall_time();
8990
}
9091

9192
/*

kernel/time/timekeeping.c

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,7 +1360,7 @@ static inline void old_vsyscall_fixup(struct timekeeper *tk)
13601360
* update_wall_time - Uses the current clocksource to increment the wall time
13611361
*
13621362
*/
1363-
static void update_wall_time(void)
1363+
void update_wall_time(void)
13641364
{
13651365
struct clocksource *clock;
13661366
struct timekeeper *real_tk = &timekeeper;
@@ -1441,19 +1441,8 @@ static void update_wall_time(void)
14411441
write_seqcount_end(&timekeeper_seq);
14421442
out:
14431443
raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
1444-
if (clock_was_set) {
1445-
/*
1446-
* XXX - I'd rather we just call clock_was_set(), but
1447-
* since we're currently holding the jiffies lock, calling
1448-
* clock_was_set would trigger an ipi which would then grab
1449-
* the jiffies lock and we'd deadlock. :(
1450-
* The right solution should probably be droping
1451-
* the jiffies lock before calling update_wall_time
1452-
* but that requires some rework of the tick sched
1453-
* code.
1454-
*/
1455-
clock_was_set_delayed();
1456-
}
1444+
if (clock_set)
1445+
clock_was_set();
14571446
}
14581447

14591448
/**
@@ -1598,7 +1587,6 @@ struct timespec get_monotonic_coarse(void)
15981587
void do_timer(unsigned long ticks)
15991588
{
16001589
jiffies_64 += ticks;
1601-
update_wall_time();
16021590
calc_global_load(ticks);
16031591
}
16041592

@@ -1756,4 +1744,5 @@ void xtime_update(unsigned long ticks)
17561744
write_seqlock(&jiffies_lock);
17571745
do_timer(ticks);
17581746
write_sequnlock(&jiffies_lock);
1747+
update_wall_time();
17591748
}

0 commit comments

Comments
 (0)