aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/hrtimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/hrtimer.c')
-rw-r--r--kernel/hrtimer.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index fd4b13b131f8..383319bae3f7 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;
@@ -1658,7 +1659,7 @@ SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,
1658/* 1659/*
1659 * Functions related to boot-time initialization: 1660 * Functions related to boot-time initialization:
1660 */ 1661 */
1661static void __cpuinit init_hrtimers_cpu(int cpu) 1662static void init_hrtimers_cpu(int cpu)
1662{ 1663{
1663 struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu); 1664 struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
1664 int i; 1665 int i;
@@ -1739,7 +1740,7 @@ static void migrate_hrtimers(int scpu)
1739 1740
1740#endif /* CONFIG_HOTPLUG_CPU */ 1741#endif /* CONFIG_HOTPLUG_CPU */
1741 1742
1742static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self, 1743static int hrtimer_cpu_notify(struct notifier_block *self,
1743 unsigned long action, void *hcpu) 1744 unsigned long action, void *hcpu)
1744{ 1745{
1745 int scpu = (long)hcpu; 1746 int scpu = (long)hcpu;
@@ -1772,7 +1773,7 @@ static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self,
1772 return NOTIFY_OK; 1773 return NOTIFY_OK;
1773} 1774}
1774 1775
1775static struct notifier_block __cpuinitdata hrtimers_nb = { 1776static struct notifier_block hrtimers_nb = {
1776 .notifier_call = hrtimer_cpu_notify, 1777 .notifier_call = hrtimer_cpu_notify,
1777}; 1778};
1778 1779