summaryrefslogtreecommitdiffstats
path: root/kernel/hrtimer.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2013-07-12 06:34:42 -0400
committerThomas Gleixner <tglx@linutronix.de>2013-07-12 06:34:42 -0400
commitf2006e27396f55276f24434f56e208d86e7f9908 (patch)
tree71896db916d33888b4286f80117d3cac0da40e6d /kernel/hrtimer.c
parente399eb56a6110e13f97e644658648602e2b08de7 (diff)
parent9903883f1dd6e86f286b7bfa6e4b423f98c1cd9e (diff)
Merge branch 'linus' into timers/urgent
Get upstream changes so we can apply fixes against them Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/hrtimer.c')
-rw-r--r--kernel/hrtimer.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index fd4b13b131f8..f0f4fe29cd21 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -47,6 +47,7 @@
47#include <linux/sched/sysctl.h> 47#include <linux/sched/sysctl.h>
48#include <linux/sched/rt.h> 48#include <linux/sched/rt.h>
49#include <linux/timer.h> 49#include <linux/timer.h>
50#include <linux/freezer.h>
50 51
51#include <asm/uaccess.h> 52#include <asm/uaccess.h>
52 53
@@ -721,17 +722,20 @@ static int hrtimer_switch_to_hres(void)
721 return 1; 722 return 1;
722} 723}
723 724
725static void clock_was_set_work(struct work_struct *work)
726{
727 clock_was_set();
728}
729
730static DECLARE_WORK(hrtimer_work, clock_was_set_work);
731
724/* 732/*
725 * Called from timekeeping code to reprogramm the hrtimer interrupt 733 * Called from timekeeping and resume code to reprogramm the hrtimer
726 * device. If called from the timer interrupt context we defer it to 734 * interrupt device on all cpus.
727 * softirq context.
728 */ 735 */
729void clock_was_set_delayed(void) 736void clock_was_set_delayed(void)
730{ 737{
731 struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); 738 schedule_work(&hrtimer_work);
732
733 cpu_base->clock_was_set = 1;
734 __raise_softirq_irqoff(HRTIMER_SOFTIRQ);
735} 739}
736 740
737#else 741#else
@@ -773,15 +777,19 @@ void clock_was_set(void)
773 777
774/* 778/*
775 * During resume we might have to reprogram the high resolution timer 779 * During resume we might have to reprogram the high resolution timer
776 * interrupt (on the local CPU): 780 * interrupt on all online CPUs. However, all other CPUs will be
781 * stopped with IRQs interrupts disabled so the clock_was_set() call
782 * must be deferred.
777 */ 783 */
778void hrtimers_resume(void) 784void hrtimers_resume(void)
779{ 785{
780 WARN_ONCE(!irqs_disabled(), 786 WARN_ONCE(!irqs_disabled(),
781 KERN_INFO "hrtimers_resume() called with IRQs enabled!"); 787 KERN_INFO "hrtimers_resume() called with IRQs enabled!");
782 788
789 /* Retrigger on the local CPU */
783 retrigger_next_event(NULL); 790 retrigger_next_event(NULL);
784 timerfd_clock_was_set(); 791 /* And schedule a retrigger for all others */
792 clock_was_set_delayed();
785} 793}
786 794
787static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer) 795static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer)
@@ -1432,13 +1440,6 @@ void hrtimer_peek_ahead_timers(void)
1432 1440
1433static void run_hrtimer_softirq(struct softirq_action *h) 1441static void run_hrtimer_softirq(struct softirq_action *h)
1434{ 1442{
1435 struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
1436
1437 if (cpu_base->clock_was_set) {
1438 cpu_base->clock_was_set = 0;
1439 clock_was_set();
1440 }
1441
1442 hrtimer_peek_ahead_timers(); 1443 hrtimer_peek_ahead_timers();
1443} 1444}
1444 1445
@@ -1545,7 +1546,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod
1545 t->task = NULL; 1546 t->task = NULL;
1546 1547
1547 if (likely(t->task)) 1548 if (likely(t->task))
1548 schedule(); 1549 freezable_schedule();
1549 1550
1550 hrtimer_cancel(&t->timer); 1551 hrtimer_cancel(&t->timer);
1551 mode = HRTIMER_MODE_ABS; 1552 mode = HRTIMER_MODE_ABS;