aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-09-07 13:37:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-09-07 13:37:48 -0400
commitebc54f278f496798a3ea1df9ae29c1055e9de95e (patch)
treebdcd1fa48c0e318a203ca1c4c048e1855cc81ec7 /kernel
parent2b12164b55e76e421c069de2cdf6b04c077983f1 (diff)
parent9bf2419fa7bffa16ce58a4d5c20399eff8c970c9 (diff)
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
Diffstat (limited to 'kernel')
-rw-r--r--kernel/compat.c24
-rw-r--r--kernel/time/tick-sched.c14
-rw-r--r--kernel/time/timekeeping.c5
3 files changed, 38 insertions, 5 deletions
diff --git a/kernel/compat.c b/kernel/compat.c
index 633394f442f8..ebb3c369d03d 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -226,7 +226,7 @@ static long compat_nanosleep_restart(struct restart_block *restart)
226 ret = hrtimer_nanosleep_restart(restart); 226 ret = hrtimer_nanosleep_restart(restart);
227 set_fs(oldfs); 227 set_fs(oldfs);
228 228
229 if (ret) { 229 if (ret == -ERESTART_RESTARTBLOCK) {
230 rmtp = restart->nanosleep.compat_rmtp; 230 rmtp = restart->nanosleep.compat_rmtp;
231 231
232 if (rmtp && compat_put_timespec(&rmt, rmtp)) 232 if (rmtp && compat_put_timespec(&rmt, rmtp))
@@ -256,7 +256,26 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,
256 HRTIMER_MODE_REL, CLOCK_MONOTONIC); 256 HRTIMER_MODE_REL, CLOCK_MONOTONIC);
257 set_fs(oldfs); 257 set_fs(oldfs);
258 258
259 if (ret) { 259 /*
260 * hrtimer_nanosleep() can only return 0 or
261 * -ERESTART_RESTARTBLOCK here because:
262 *
263 * - we call it with HRTIMER_MODE_REL and therefor exclude the
264 * -ERESTARTNOHAND return path.
265 *
266 * - we supply the rmtp argument from the task stack (due to
267 * the necessary compat conversion. So the update cannot
268 * fail, which excludes the -EFAULT return path as well. If
269 * it fails nevertheless we have a bigger problem and wont
270 * reach this place anymore.
271 *
272 * - if the return value is 0, we do not have to update rmtp
273 * because there is no remaining time.
274 *
275 * We check for -ERESTART_RESTARTBLOCK nevertheless if the
276 * core implementation decides to return random nonsense.
277 */
278 if (ret == -ERESTART_RESTARTBLOCK) {
260 struct restart_block *restart 279 struct restart_block *restart
261 = &current_thread_info()->restart_block; 280 = &current_thread_info()->restart_block;
262 281
@@ -266,7 +285,6 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,
266 if (rmtp && compat_put_timespec(&rmt, rmtp)) 285 if (rmtp && compat_put_timespec(&rmt, rmtp))
267 return -EFAULT; 286 return -EFAULT;
268 } 287 }
269
270 return ret; 288 return ret;
271} 289}
272 290
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 99aa6ee3908f..f654a8a298fa 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -225,6 +225,20 @@ static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) = {
225}; 225};
226 226
227/* 227/*
228 * Kick this CPU if it's full dynticks in order to force it to
229 * re-evaluate its dependency on the tick and restart it if necessary.
230 * This kick, unlike tick_nohz_full_kick_cpu() and tick_nohz_full_kick_all(),
231 * is NMI safe.
232 */
233void tick_nohz_full_kick(void)
234{
235 if (!tick_nohz_full_cpu(smp_processor_id()))
236 return;
237
238 irq_work_queue(&__get_cpu_var(nohz_full_kick_work));
239}
240
241/*
228 * Kick the CPU if it's full dynticks in order to force it to 242 * Kick the CPU if it's full dynticks in order to force it to
229 * re-evaluate its dependency on the tick and restart it if necessary. 243 * re-evaluate its dependency on the tick and restart it if necessary.
230 */ 244 */
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index fb4a9c2cf8d9..ec1791fae965 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -442,11 +442,12 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action)
442 tk->ntp_error = 0; 442 tk->ntp_error = 0;
443 ntp_clear(); 443 ntp_clear();
444 } 444 }
445 update_vsyscall(tk);
446 update_pvclock_gtod(tk, action & TK_CLOCK_WAS_SET);
447 445
448 tk_update_ktime_data(tk); 446 tk_update_ktime_data(tk);
449 447
448 update_vsyscall(tk);
449 update_pvclock_gtod(tk, action & TK_CLOCK_WAS_SET);
450
450 if (action & TK_MIRROR) 451 if (action & TK_MIRROR)
451 memcpy(&shadow_timekeeper, &tk_core.timekeeper, 452 memcpy(&shadow_timekeeper, &tk_core.timekeeper,
452 sizeof(tk_core.timekeeper)); 453 sizeof(tk_core.timekeeper));