clock events: allow replacement of broadcast timer
Venki Pallipadi [Fri, 12 Oct 2007 21:04:23 +0000 (23:04 +0200)]
Change the broadcast timer, if a timer with higher rating becomes available.

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Cc: Andi Kleen <ak@suse.de>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

kernel/time/tick-broadcast.c
kernel/time/tick-common.c

index acf15b4..298bc7c 100644 (file)
@@ -64,8 +64,9 @@ static void tick_broadcast_start_periodic(struct clock_event_device *bc)
  */
 int tick_check_broadcast_device(struct clock_event_device *dev)
 {
-       if (tick_broadcast_device.evtdev ||
-           (dev->features & CLOCK_EVT_FEAT_C3STOP))
+       if ((tick_broadcast_device.evtdev &&
+            tick_broadcast_device.evtdev->rating >= dev->rating) ||
+            (dev->features & CLOCK_EVT_FEAT_C3STOP))
                return 0;
 
        clockevents_exchange_device(NULL, dev);
@@ -513,11 +514,9 @@ static void tick_broadcast_clear_oneshot(int cpu)
  */
 void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
 {
-       if (bc->mode != CLOCK_EVT_MODE_ONESHOT) {
-               bc->event_handler = tick_handle_oneshot_broadcast;
-               clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
-               bc->next_event.tv64 = KTIME_MAX;
-       }
+       bc->event_handler = tick_handle_oneshot_broadcast;
+       clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
+       bc->next_event.tv64 = KTIME_MAX;
 }
 
 /*
index 77a21ab..3f3ae39 100644 (file)
@@ -200,7 +200,7 @@ static int tick_check_new_device(struct clock_event_device *newdev)
 
        cpu = smp_processor_id();
        if (!cpu_isset(cpu, newdev->cpumask))
-               goto out;
+               goto out_bc;
 
        td = &per_cpu(tick_cpu_device, cpu);
        curdev = td->evtdev;
@@ -265,7 +265,7 @@ out_bc:
         */
        if (tick_check_broadcast_device(newdev))
                ret = NOTIFY_STOP;
-out:
+
        spin_unlock_irqrestore(&tick_device_lock, flags);
 
        return ret;