Commit ebc54f27 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer fixes from Thomas Gleixner:
 "Three fixlets from the timer departement:

   - Update the timekeeper before updating vsyscall and pvclock.  This
     fixes the kvm-clock regression reported by Chris and Paolo.

   - Use the proper irq work interface from NMI.  This fixes the
     regression reported by Catalin and Dave.

   - Clarify the compat_nanosleep error handling mechanism to avoid
     future confusion"

* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  timekeeping: Update timekeeper before updating vsyscall and pvclock
  compat: nanosleep: Clarify error handling
  nohz: Restore NMI safe local irq work for local nohz kick
parents 2b12164b 9bf2419f
...@@ -183,13 +183,8 @@ static inline bool tick_nohz_full_cpu(int cpu) ...@@ -183,13 +183,8 @@ static inline bool tick_nohz_full_cpu(int cpu)
extern void tick_nohz_init(void); extern void tick_nohz_init(void);
extern void __tick_nohz_full_check(void); extern void __tick_nohz_full_check(void);
extern void tick_nohz_full_kick(void);
extern void tick_nohz_full_kick_cpu(int cpu); extern void tick_nohz_full_kick_cpu(int cpu);
static inline void tick_nohz_full_kick(void)
{
tick_nohz_full_kick_cpu(smp_processor_id());
}
extern void tick_nohz_full_kick_all(void); extern void tick_nohz_full_kick_all(void);
extern void __tick_nohz_task_switch(struct task_struct *tsk); extern void __tick_nohz_task_switch(struct task_struct *tsk);
#else #else
......
...@@ -226,7 +226,7 @@ static long compat_nanosleep_restart(struct restart_block *restart) ...@@ -226,7 +226,7 @@ static long compat_nanosleep_restart(struct restart_block *restart)
ret = hrtimer_nanosleep_restart(restart); ret = hrtimer_nanosleep_restart(restart);
set_fs(oldfs); set_fs(oldfs);
if (ret) { if (ret == -ERESTART_RESTARTBLOCK) {
rmtp = restart->nanosleep.compat_rmtp; rmtp = restart->nanosleep.compat_rmtp;
if (rmtp && compat_put_timespec(&rmt, rmtp)) if (rmtp && compat_put_timespec(&rmt, rmtp))
...@@ -256,7 +256,26 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp, ...@@ -256,7 +256,26 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,
HRTIMER_MODE_REL, CLOCK_MONOTONIC); HRTIMER_MODE_REL, CLOCK_MONOTONIC);
set_fs(oldfs); set_fs(oldfs);
if (ret) { /*
* hrtimer_nanosleep() can only return 0 or
* -ERESTART_RESTARTBLOCK here because:
*
* - we call it with HRTIMER_MODE_REL and therefor exclude the
* -ERESTARTNOHAND return path.
*
* - we supply the rmtp argument from the task stack (due to
* the necessary compat conversion. So the update cannot
* fail, which excludes the -EFAULT return path as well. If
* it fails nevertheless we have a bigger problem and wont
* reach this place anymore.
*
* - if the return value is 0, we do not have to update rmtp
* because there is no remaining time.
*
* We check for -ERESTART_RESTARTBLOCK nevertheless if the
* core implementation decides to return random nonsense.
*/
if (ret == -ERESTART_RESTARTBLOCK) {
struct restart_block *restart struct restart_block *restart
= &current_thread_info()->restart_block; = &current_thread_info()->restart_block;
...@@ -266,7 +285,6 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp, ...@@ -266,7 +285,6 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,
if (rmtp && compat_put_timespec(&rmt, rmtp)) if (rmtp && compat_put_timespec(&rmt, rmtp))
return -EFAULT; return -EFAULT;
} }
return ret; return ret;
} }
......
...@@ -224,6 +224,20 @@ static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) = { ...@@ -224,6 +224,20 @@ static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) = {
.func = nohz_full_kick_work_func, .func = nohz_full_kick_work_func,
}; };
/*
* Kick this CPU if it's full dynticks in order to force it to
* re-evaluate its dependency on the tick and restart it if necessary.
* This kick, unlike tick_nohz_full_kick_cpu() and tick_nohz_full_kick_all(),
* is NMI safe.
*/
void tick_nohz_full_kick(void)
{
if (!tick_nohz_full_cpu(smp_processor_id()))
return;
irq_work_queue(&__get_cpu_var(nohz_full_kick_work));
}
/* /*
* Kick the CPU if it's full dynticks in order to force it to * Kick the CPU if it's full dynticks in order to force it to
* re-evaluate its dependency on the tick and restart it if necessary. * re-evaluate its dependency on the tick and restart it if necessary.
......
...@@ -442,11 +442,12 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action) ...@@ -442,11 +442,12 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action)
tk->ntp_error = 0; tk->ntp_error = 0;
ntp_clear(); ntp_clear();
} }
update_vsyscall(tk);
update_pvclock_gtod(tk, action & TK_CLOCK_WAS_SET);
tk_update_ktime_data(tk); tk_update_ktime_data(tk);
update_vsyscall(tk);
update_pvclock_gtod(tk, action & TK_CLOCK_WAS_SET);
if (action & TK_MIRROR) if (action & TK_MIRROR)
memcpy(&shadow_timekeeper, &tk_core.timekeeper, memcpy(&shadow_timekeeper, &tk_core.timekeeper,
sizeof(tk_core.timekeeper)); sizeof(tk_core.timekeeper));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment