Skip to content

Commit

Permalink
tick/timekeeping: Call update_wall_time outside the jiffies lock
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
John Stultz committed Dec 23, 2013
1 parent 6fdda9a commit 47a1b79
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 15 deletions.
1 change: 1 addition & 0 deletions kernel/time/tick-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ static void tick_periodic(int cpu)

do_timer(1);
write_sequnlock(&jiffies_lock);
update_wall_time();
}

update_process_times(user_mode(get_irq_regs()));
Expand Down
1 change: 1 addition & 0 deletions kernel/time/tick-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,4 @@ static inline int tick_device_is_functional(struct clock_event_device *dev)
#endif

extern void do_timer(unsigned long ticks);
extern void update_wall_time(void);
1 change: 1 addition & 0 deletions kernel/time/tick-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ static void tick_do_update_jiffies64(ktime_t now)
tick_next_period = ktime_add(last_jiffies_update, tick_period);
}
write_sequnlock(&jiffies_lock);
update_wall_time();
}

/*
Expand Down
19 changes: 4 additions & 15 deletions kernel/time/timekeeping.c
Original file line number Diff line number Diff line change
Expand Up @@ -1360,7 +1360,7 @@ static inline void old_vsyscall_fixup(struct timekeeper *tk)
* update_wall_time - Uses the current clocksource to increment the wall time
*
*/
static void update_wall_time(void)
void update_wall_time(void)
{
struct clocksource *clock;
struct timekeeper *real_tk = &timekeeper;
Expand Down Expand Up @@ -1441,19 +1441,8 @@ static void update_wall_time(void)
write_seqcount_end(&timekeeper_seq);
out:
raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
if (clock_was_set) {
/*
* XXX - I'd rather we just call clock_was_set(), but
* since we're currently holding the jiffies lock, calling
* clock_was_set would trigger an ipi which would then grab
* the jiffies lock and we'd deadlock. :(
* The right solution should probably be droping
* the jiffies lock before calling update_wall_time
* but that requires some rework of the tick sched
* code.
*/
clock_was_set_delayed();
}
if (clock_set)
clock_was_set();
}

/**
Expand Down Expand Up @@ -1598,7 +1587,6 @@ struct timespec get_monotonic_coarse(void)
void do_timer(unsigned long ticks)
{
jiffies_64 += ticks;
update_wall_time();
calc_global_load(ticks);
}

Expand Down Expand Up @@ -1756,4 +1744,5 @@ void xtime_update(unsigned long ticks)
write_seqlock(&jiffies_lock);
do_timer(ticks);
write_sequnlock(&jiffies_lock);
update_wall_time();
}

0 comments on commit 47a1b79

Please sign in to comment.