diff options
author | Andi Kleen <ak@linux.intel.com> | 2011-05-04 18:09:27 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2011-05-05 11:32:13 -0400 |
commit | 7372b0b122af0f6675f3ab65bfd91c8a438e0480 (patch) | |
tree | 5dcd0f94e0064b76573837da09ca5277b7e5f068 | |
parent | 179eb03268aa1da03d90f1566ea85dc1478d3ae3 (diff) |
clockevents: Move C3 stop test outside lock
Avoid taking broadcast_lock in the idle path for systems where the
timer doesn't stop in C3.
[ tglx: Removed the stale label and added comment ]
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Cc: Dave Kleikamp <dkleikamp@gmail.com>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: lenb@kernel.org
Cc: paulmck@us.ibm.com
Link: http://lkml.kernel.org/r/%3C20110504234806.GF2925%40one.firstfloor.org%3E
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | kernel/time/tick-broadcast.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index da800ffa810c..827e0f862da4 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
@@ -456,23 +456,27 @@ void tick_broadcast_oneshot_control(unsigned long reason) | |||
456 | unsigned long flags; | 456 | unsigned long flags; |
457 | int cpu; | 457 | int cpu; |
458 | 458 | ||
459 | raw_spin_lock_irqsave(&tick_broadcast_lock, flags); | ||
460 | |||
461 | /* | 459 | /* |
462 | * Periodic mode does not care about the enter/exit of power | 460 | * Periodic mode does not care about the enter/exit of power |
463 | * states | 461 | * states |
464 | */ | 462 | */ |
465 | if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) | 463 | if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) |
466 | goto out; | 464 | return; |
467 | 465 | ||
468 | bc = tick_broadcast_device.evtdev; | 466 | /* |
467 | * We are called with preemtion disabled from the depth of the | ||
468 | * idle code, so we can't be moved away. | ||
469 | */ | ||
469 | cpu = smp_processor_id(); | 470 | cpu = smp_processor_id(); |
470 | td = &per_cpu(tick_cpu_device, cpu); | 471 | td = &per_cpu(tick_cpu_device, cpu); |
471 | dev = td->evtdev; | 472 | dev = td->evtdev; |
472 | 473 | ||
473 | if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) | 474 | if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) |
474 | goto out; | 475 | return; |
476 | |||
477 | bc = tick_broadcast_device.evtdev; | ||
475 | 478 | ||
479 | raw_spin_lock_irqsave(&tick_broadcast_lock, flags); | ||
476 | if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) { | 480 | if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) { |
477 | if (!cpumask_test_cpu(cpu, tick_get_broadcast_oneshot_mask())) { | 481 | if (!cpumask_test_cpu(cpu, tick_get_broadcast_oneshot_mask())) { |
478 | cpumask_set_cpu(cpu, tick_get_broadcast_oneshot_mask()); | 482 | cpumask_set_cpu(cpu, tick_get_broadcast_oneshot_mask()); |
@@ -489,8 +493,6 @@ void tick_broadcast_oneshot_control(unsigned long reason) | |||
489 | tick_program_event(dev->next_event, 1); | 493 | tick_program_event(dev->next_event, 1); |
490 | } | 494 | } |
491 | } | 495 | } |
492 | |||
493 | out: | ||
494 | raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 496 | raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
495 | } | 497 | } |
496 | 498 | ||