aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/tick.h5
-rw-r--r--kernel/time/tick-sched.c48
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);
71extern struct tick_device *tick_get_device(int cpu); 71extern 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
74extern int tick_init_highres(void); 79extern int tick_init_highres(void);
75extern int tick_program_event(ktime_t expires, int force); 80extern int tick_program_event(ktime_t expires, int force);
76extern void tick_setup_sched_timer(void); 81extern 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 */
693int quanta_type = LINUX_DEFAULT_TICKS;
694static 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
708u64 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 */
691void tick_setup_sched_timer(void) 731void 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 (;;) {