Merge branch 'timers/posix-cpu-timers-for-tglx' of
[firefly-linux-kernel-4.4.55.git] / kernel / time / tick-broadcast.c
index 4430fa695b48edbeadc632d06be8b922d6426ba6..6d3f91631de62cd94e2c216e96ac56092332e126 100644 (file)
@@ -583,6 +583,12 @@ again:
                }
        }
 
+       /*
+        * Remove the current cpu from the pending mask. The event is
+        * delivered immediately in tick_do_broadcast() !
+        */
+       cpumask_clear_cpu(smp_processor_id(), tick_broadcast_pending_mask);
+
        /* Take care of enforced broadcast requests */
        cpumask_or(tmpmask, tmpmask, tick_broadcast_force_mask);
        cpumask_clear(tick_broadcast_force_mask);
@@ -654,8 +660,8 @@ void tick_broadcast_oneshot_control(unsigned long reason)
 
        raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
        if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) {
-               WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask));
                if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) {
+                       WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask));
                        clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN);
                        /*
                         * We only reprogram the broadcast timer if we
@@ -672,8 +678,6 @@ void tick_broadcast_oneshot_control(unsigned long reason)
        } else {
                if (cpumask_test_and_clear_cpu(cpu, tick_broadcast_oneshot_mask)) {
                        clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT);
-                       if (dev->next_event.tv64 == KTIME_MAX)
-                               goto out;
                        /*
                         * The cpu which was handling the broadcast
                         * timer marked this cpu in the broadcast
@@ -687,6 +691,11 @@ void tick_broadcast_oneshot_control(unsigned long reason)
                                       tick_broadcast_pending_mask))
                                goto out;
 
+                       /*
+                        * Bail out if there is no next event.
+                        */
+                       if (dev->next_event.tv64 == KTIME_MAX)
+                               goto out;
                        /*
                         * If the pending bit is not set, then we are
                         * either the CPU handling the broadcast
@@ -771,10 +780,6 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
 
                bc->event_handler = tick_handle_oneshot_broadcast;
 
-               /* Take the do_timer update */
-               if (!tick_nohz_full_cpu(cpu))
-                       tick_do_timer_cpu = cpu;
-
                /*
                 * We must be careful here. There might be other CPUs
                 * waiting for periodic broadcast. We need to set the