diff options
Diffstat (limited to 'kernel/time/tick-sched.c')
-rw-r--r-- | kernel/time/tick-sched.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 3e216e01bbd1..bb2d8b7850a3 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -768,12 +768,53 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) | |||
768 | } | 768 | } |
769 | 769 | ||
770 | /** | 770 | /** |
771 | * tick_set_quanta_type - get the quanta type as a boot option | ||
772 | * Default is standard setup with ticks staggered over first | ||
773 | * half of tick period. | ||
774 | */ | ||
775 | int quanta_type = LINUX_DEFAULT_TICKS; | ||
776 | static int __init tick_set_quanta_type(char *str) | ||
777 | { | ||
778 | if (strcmp("aligned", str) == 0) { | ||
779 | quanta_type = LITMUS_ALIGNED_TICKS; | ||
780 | printk(KERN_INFO "LITMUS^RT: setting aligned quanta\n"); | ||
781 | } | ||
782 | else if (strcmp("staggered", str) == 0) { | ||
783 | quanta_type = LITMUS_STAGGERED_TICKS; | ||
784 | printk(KERN_INFO "LITMUS^RT: setting staggered quanta\n"); | ||
785 | } | ||
786 | return 1; | ||
787 | } | ||
788 | __setup("quanta=", tick_set_quanta_type); | ||
789 | |||
790 | u64 cpu_stagger_offset(int cpu) | ||
791 | { | ||
792 | u64 offset = 0; | ||
793 | switch (quanta_type) { | ||
794 | case LITMUS_ALIGNED_TICKS: | ||
795 | offset = 0; | ||
796 | break; | ||
797 | case LITMUS_STAGGERED_TICKS: | ||
798 | offset = ktime_to_ns(tick_period); | ||
799 | do_div(offset, num_possible_cpus()); | ||
800 | offset *= cpu; | ||
801 | break; | ||
802 | default: | ||
803 | offset = ktime_to_ns(tick_period) >> 1; | ||
804 | do_div(offset, num_possible_cpus()); | ||
805 | offset *= cpu; | ||
806 | } | ||
807 | return offset; | ||
808 | } | ||
809 | |||
810 | /** | ||
771 | * tick_setup_sched_timer - setup the tick emulation timer | 811 | * tick_setup_sched_timer - setup the tick emulation timer |
772 | */ | 812 | */ |
773 | void tick_setup_sched_timer(void) | 813 | void tick_setup_sched_timer(void) |
774 | { | 814 | { |
775 | struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); | 815 | struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); |
776 | ktime_t now = ktime_get(); | 816 | ktime_t now = ktime_get(); |
817 | u64 offset; | ||
777 | 818 | ||
778 | /* | 819 | /* |
779 | * Emulate tick processing via per-CPU hrtimers: | 820 | * Emulate tick processing via per-CPU hrtimers: |
@@ -784,6 +825,12 @@ void tick_setup_sched_timer(void) | |||
784 | /* Get the next period (per cpu) */ | 825 | /* Get the next period (per cpu) */ |
785 | hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update()); | 826 | hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update()); |
786 | 827 | ||
828 | /* Offset must be set correctly to achieve desired quanta type. */ | ||
829 | offset = cpu_stagger_offset(smp_processor_id()); | ||
830 | |||
831 | /* Add the correct offset to expiration time */ | ||
832 | hrtimer_add_expires_ns(&ts->sched_timer, offset); | ||
833 | |||
787 | for (;;) { | 834 | for (;;) { |
788 | hrtimer_forward(&ts->sched_timer, now, tick_period); | 835 | hrtimer_forward(&ts->sched_timer, now, tick_period); |
789 | hrtimer_start_expires(&ts->sched_timer, | 836 | hrtimer_start_expires(&ts->sched_timer, |