diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2011-08-27 09:43:54 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2011-08-27 10:06:11 -0400 |
commit | 7b1bb388bc879ffcc6c69b567816d5c354afe42b (patch) | |
tree | 5a217fdfb0b5e5a327bdcd624506337c1ae1fe32 /kernel/time/tick-broadcast.c | |
parent | 7d754596756240fa918b94cd0c3011c77a638987 (diff) | |
parent | 02f8c6aee8df3cdc935e9bdd4f2d020306035dbe (diff) |
Merge 'Linux v3.0' into Litmus
Some notes:
* Litmus^RT scheduling class is the topmost scheduling class
(above stop_sched_class).
* scheduler_ipi() function (e.g., in smp_reschedule_interrupt())
may increase IPI latencies.
* Added path into schedule() to quickly re-evaluate scheduling
decision without becoming preemptive again. This used to be
a standard path before the removal of BKL.
Conflicts:
Makefile
arch/arm/kernel/calls.S
arch/arm/kernel/smp.c
arch/x86/include/asm/unistd_32.h
arch/x86/kernel/smp.c
arch/x86/kernel/syscall_table_32.S
include/linux/hrtimer.h
kernel/printk.c
kernel/sched.c
kernel/sched_fair.c
Diffstat (limited to 'kernel/time/tick-broadcast.c')
-rw-r--r-- | kernel/time/tick-broadcast.c | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 48b2761b5668..c7218d132738 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/percpu.h> | 18 | #include <linux/percpu.h> |
19 | #include <linux/profile.h> | 19 | #include <linux/profile.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/tick.h> | ||
22 | 21 | ||
23 | #include "tick-internal.h" | 22 | #include "tick-internal.h" |
24 | 23 | ||
@@ -457,23 +456,27 @@ void tick_broadcast_oneshot_control(unsigned long reason) | |||
457 | unsigned long flags; | 456 | unsigned long flags; |
458 | int cpu; | 457 | int cpu; |
459 | 458 | ||
460 | raw_spin_lock_irqsave(&tick_broadcast_lock, flags); | ||
461 | |||
462 | /* | 459 | /* |
463 | * Periodic mode does not care about the enter/exit of power | 460 | * Periodic mode does not care about the enter/exit of power |
464 | * states | 461 | * states |
465 | */ | 462 | */ |
466 | if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) | 463 | if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) |
467 | goto out; | 464 | return; |
468 | 465 | ||
469 | 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 | */ | ||
470 | cpu = smp_processor_id(); | 470 | cpu = smp_processor_id(); |
471 | td = &per_cpu(tick_cpu_device, cpu); | 471 | td = &per_cpu(tick_cpu_device, cpu); |
472 | dev = td->evtdev; | 472 | dev = td->evtdev; |
473 | 473 | ||
474 | if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) | 474 | if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) |
475 | goto out; | 475 | return; |
476 | |||
477 | bc = tick_broadcast_device.evtdev; | ||
476 | 478 | ||
479 | raw_spin_lock_irqsave(&tick_broadcast_lock, flags); | ||
477 | if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) { | 480 | if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) { |
478 | if (!cpumask_test_cpu(cpu, tick_get_broadcast_oneshot_mask())) { | 481 | if (!cpumask_test_cpu(cpu, tick_get_broadcast_oneshot_mask())) { |
479 | cpumask_set_cpu(cpu, tick_get_broadcast_oneshot_mask()); | 482 | cpumask_set_cpu(cpu, tick_get_broadcast_oneshot_mask()); |
@@ -490,8 +493,6 @@ void tick_broadcast_oneshot_control(unsigned long reason) | |||
490 | tick_program_event(dev->next_event, 1); | 493 | tick_program_event(dev->next_event, 1); |
491 | } | 494 | } |
492 | } | 495 | } |
493 | |||
494 | out: | ||
495 | raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 496 | raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
496 | } | 497 | } |
497 | 498 | ||
@@ -523,10 +524,11 @@ static void tick_broadcast_init_next_event(struct cpumask *mask, | |||
523 | */ | 524 | */ |
524 | void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | 525 | void tick_broadcast_setup_oneshot(struct clock_event_device *bc) |
525 | { | 526 | { |
527 | int cpu = smp_processor_id(); | ||
528 | |||
526 | /* Set it up only once ! */ | 529 | /* Set it up only once ! */ |
527 | if (bc->event_handler != tick_handle_oneshot_broadcast) { | 530 | if (bc->event_handler != tick_handle_oneshot_broadcast) { |
528 | int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC; | 531 | int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC; |
529 | int cpu = smp_processor_id(); | ||
530 | 532 | ||
531 | bc->event_handler = tick_handle_oneshot_broadcast; | 533 | bc->event_handler = tick_handle_oneshot_broadcast; |
532 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); | 534 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); |
@@ -552,6 +554,15 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | |||
552 | tick_broadcast_set_event(tick_next_period, 1); | 554 | tick_broadcast_set_event(tick_next_period, 1); |
553 | } else | 555 | } else |
554 | bc->next_event.tv64 = KTIME_MAX; | 556 | bc->next_event.tv64 = KTIME_MAX; |
557 | } else { | ||
558 | /* | ||
559 | * The first cpu which switches to oneshot mode sets | ||
560 | * the bit for all other cpus which are in the general | ||
561 | * (periodic) broadcast mask. So the bit is set and | ||
562 | * would prevent the first broadcast enter after this | ||
563 | * to program the bc device. | ||
564 | */ | ||
565 | tick_broadcast_clear_oneshot(cpu); | ||
555 | } | 566 | } |
556 | } | 567 | } |
557 | 568 | ||
@@ -600,4 +611,14 @@ int tick_broadcast_oneshot_active(void) | |||
600 | return tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT; | 611 | return tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT; |
601 | } | 612 | } |
602 | 613 | ||
614 | /* | ||
615 | * Check whether the broadcast device supports oneshot. | ||
616 | */ | ||
617 | bool tick_broadcast_oneshot_available(void) | ||
618 | { | ||
619 | struct clock_event_device *bc = tick_broadcast_device.evtdev; | ||
620 | |||
621 | return bc ? bc->features & CLOCK_EVT_FEAT_ONESHOT : false; | ||
622 | } | ||
623 | |||
603 | #endif | 624 | #endif |