diff options
-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 0482229c07db..4f9ba058abdb 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 89aed5933ed4..dcbff7515489 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 (;;) { |