diff options
| author | Andrea Bastoni <bastoni@cs.unc.edu> | 2009-12-17 21:30:47 -0500 |
|---|---|---|
| committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-29 17:14:32 -0400 |
| commit | 4e593e7105dec02e62ea7a1812dccb35a0d56d01 (patch) | |
| tree | 3a162c327c9a5ef741bbf6da662cd02edcb9f309 | |
| parent | 1d823f50678d7cc3bf72bf89ec0bddc7338e23d5 (diff) | |
[ported from 2008.3] Add support for quantum alignment
| -rw-r--r-- | include/linux/tick.h | 5 | ||||
| -rw-r--r-- | kernel/time/tick-sched.c | 48 |
2 files changed, 50 insertions, 3 deletions
diff --git a/include/linux/tick.h b/include/linux/tick.h index 0482229c07d..4f9ba058abd 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h | |||
| @@ -71,6 +71,11 @@ extern int tick_is_oneshot_available(void); | |||
| 71 | extern struct tick_device *tick_get_device(int cpu); | 71 | extern struct tick_device *tick_get_device(int cpu); |
| 72 | 72 | ||
| 73 | # ifdef CONFIG_HIGH_RES_TIMERS | 73 | # ifdef CONFIG_HIGH_RES_TIMERS |
| 74 | /* LITMUS^RT tick alignment */ | ||
| 75 | #define LINUX_DEFAULT_TICKS 0 | ||
| 76 | #define LITMUS_ALIGNED_TICKS 1 | ||
| 77 | #define LITMUS_STAGGERED_TICKS 2 | ||
| 78 | |||
| 74 | extern int tick_init_highres(void); | 79 | extern int tick_init_highres(void); |
| 75 | extern int tick_program_event(ktime_t expires, int force); | 80 | extern int tick_program_event(ktime_t expires, int force); |
| 76 | extern void tick_setup_sched_timer(void); | 81 | extern void tick_setup_sched_timer(void); |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 89aed5933ed..dcbff751548 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
| @@ -686,6 +686,46 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) | |||
| 686 | } | 686 | } |
| 687 | 687 | ||
| 688 | /** | 688 | /** |
| 689 | * tick_set_quanta_type - get the quanta type as a boot option | ||
| 690 | * Default is standard setup with ticks staggered over first | ||
| 691 | * half of tick period. | ||
| 692 | */ | ||
| 693 | int quanta_type = LINUX_DEFAULT_TICKS; | ||
| 694 | static int __init tick_set_quanta_type(char *str) | ||
| 695 | { | ||
| 696 | if (strcmp("aligned", str) == 0) { | ||
| 697 | quanta_type = LITMUS_ALIGNED_TICKS; | ||
| 698 | printk(KERN_INFO "LITMUS^RT: setting aligned quanta\n"); | ||
| 699 | } | ||
| 700 | else if (strcmp("staggered", str) == 0) { | ||
| 701 | quanta_type = LITMUS_STAGGERED_TICKS; | ||
| 702 | printk(KERN_INFO "LITMUS^RT: setting staggered quanta\n"); | ||
| 703 | } | ||
| 704 | return 1; | ||
| 705 | } | ||
| 706 | __setup("quanta=", tick_set_quanta_type); | ||
| 707 | |||
| 708 | u64 cpu_stagger_offset(int cpu) | ||
| 709 | { | ||
| 710 | u64 offset = 0; | ||
| 711 | switch (quanta_type) { | ||
| 712 | case LITMUS_ALIGNED_TICKS: | ||
| 713 | offset = 0; | ||
| 714 | break; | ||
| 715 | case LITMUS_STAGGERED_TICKS: | ||
| 716 | offset = ktime_to_ns(tick_period); | ||
| 717 | do_div(offset, num_possible_cpus()); | ||
| 718 | offset *= cpu; | ||
| 719 | break; | ||
| 720 | default: | ||
| 721 | offset = ktime_to_ns(tick_period) >> 1; | ||
| 722 | do_div(offset, num_possible_cpus()); | ||
| 723 | offset *= cpu; | ||
| 724 | } | ||
| 725 | return offset; | ||
| 726 | } | ||
| 727 | |||
| 728 | /** | ||
| 689 | * tick_setup_sched_timer - setup the tick emulation timer | 729 | * tick_setup_sched_timer - setup the tick emulation timer |
| 690 | */ | 730 | */ |
| 691 | void tick_setup_sched_timer(void) | 731 | void tick_setup_sched_timer(void) |
| @@ -702,9 +742,11 @@ void tick_setup_sched_timer(void) | |||
| 702 | 742 | ||
| 703 | /* Get the next period (per cpu) */ | 743 | /* Get the next period (per cpu) */ |
| 704 | hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update()); | 744 | hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update()); |
| 705 | offset = ktime_to_ns(tick_period) >> 1; | 745 | |
| 706 | do_div(offset, num_possible_cpus()); | 746 | /* Offset must be set correctly to achieve desired quanta type. */ |
| 707 | offset *= smp_processor_id(); | 747 | offset = cpu_stagger_offset(smp_processor_id()); |
| 748 | |||
| 749 | /* Add the correct offset to expiration time */ | ||
| 708 | hrtimer_add_expires_ns(&ts->sched_timer, offset); | 750 | hrtimer_add_expires_ns(&ts->sched_timer, offset); |
| 709 | 751 | ||
| 710 | for (;;) { | 752 | for (;;) { |
