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
This commit is contained in:
Коммит
ebc54f278f
|
@ -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)
|
||||||
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,
|
||||||
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
|
||||||
= ¤t_thread_info()->restart_block;
|
= ¤t_thread_info()->restart_block;
|
||||||
|
|
||||||
|
@ -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) = {
|
||||||
.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)
|
||||||
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));
|
||||||
|
|
Загрузка…
Ссылка в новой задаче