ALSA: asihpi: Fix unlocked snd_pcm_stop() call
[deliverable/linux.git] / kernel / hrtimer.c
index e86827e94c9ab31f26a12b896e5480da8f8b3e4b..f0f4fe29cd21b1df3a60424bb8693b1892c17b8a 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/sched/sysctl.h>
 #include <linux/sched/rt.h>
 #include <linux/timer.h>
+#include <linux/freezer.h>
 
 #include <asm/uaccess.h>
 
@@ -721,17 +722,20 @@ static int hrtimer_switch_to_hres(void)
        return 1;
 }
 
+static void clock_was_set_work(struct work_struct *work)
+{
+       clock_was_set();
+}
+
+static DECLARE_WORK(hrtimer_work, clock_was_set_work);
+
 /*
- * Called from timekeeping code to reprogramm the hrtimer interrupt
- * device. If called from the timer interrupt context we defer it to
- * softirq context.
+ * Called from timekeeping and resume code to reprogramm the hrtimer
+ * interrupt device on all cpus.
  */
 void clock_was_set_delayed(void)
 {
-       struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
-
-       cpu_base->clock_was_set = 1;
-       __raise_softirq_irqoff(HRTIMER_SOFTIRQ);
+       schedule_work(&hrtimer_work);
 }
 
 #else
@@ -775,22 +779,17 @@ void clock_was_set(void)
  * During resume we might have to reprogram the high resolution timer
  * interrupt on all online CPUs.  However, all other CPUs will be
  * stopped with IRQs interrupts disabled so the clock_was_set() call
- * must be deferred to the softirq.
- *
- * The one-shot timer has already been programmed to fire immediately
- * (see tick_resume_oneshot()) and this interrupt will trigger the
- * softirq to run early enough to correctly reprogram the timers on
- * all CPUs.
+ * must be deferred.
  */
 void hrtimers_resume(void)
 {
-       struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
-
        WARN_ONCE(!irqs_disabled(),
                  KERN_INFO "hrtimers_resume() called with IRQs enabled!");
 
-       cpu_base->clock_was_set = 1;
-       __raise_softirq_irqoff(HRTIMER_SOFTIRQ);
+       /* Retrigger on the local CPU */
+       retrigger_next_event(NULL);
+       /* And schedule a retrigger for all others */
+       clock_was_set_delayed();
 }
 
 static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer)
@@ -1441,13 +1440,6 @@ void hrtimer_peek_ahead_timers(void)
 
 static void run_hrtimer_softirq(struct softirq_action *h)
 {
-       struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
-
-       if (cpu_base->clock_was_set) {
-               cpu_base->clock_was_set = 0;
-               clock_was_set();
-       }
-
        hrtimer_peek_ahead_timers();
 }
 
@@ -1554,7 +1546,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod
                        t->task = NULL;
 
                if (likely(t->task))
-                       schedule();
+                       freezable_schedule();
 
                hrtimer_cancel(&t->timer);
                mode = HRTIMER_MODE_ABS;
This page took 0.103223 seconds and 5 git commands to generate.