aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Cerqueira <felipec@mpi-sws.org>2013-02-12 11:50:12 -0500
committerBjoern Brandenburg <bbb@mpi-sws.org>2013-08-07 03:46:41 -0400
commit05ad941dfa83599208ee11b67c49ad54c4f3b78a (patch)
tree6c28687378286d6777c2980930ef487243d8fc8c
parent01a0a30a003019092e7748049a03bb5cfd0ab918 (diff)
Add quantum aligment code
Enable staggered ticks for PD^2.
-rw-r--r--include/linux/tick.h5
-rw-r--r--kernel/time/tick-sched.c56
2 files changed, 54 insertions, 7 deletions
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 9180f4b85e6d..45fd00e4051b 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -77,6 +77,11 @@ extern int tick_is_oneshot_available(void);
77extern struct tick_device *tick_get_device(int cpu); 77extern struct tick_device *tick_get_device(int cpu);
78 78
79# ifdef CONFIG_HIGH_RES_TIMERS 79# ifdef CONFIG_HIGH_RES_TIMERS
80/* LITMUS^RT tick alignment */
81#define LINUX_DEFAULT_TICKS 0
82#define LITMUS_ALIGNED_TICKS 1
83#define LITMUS_STAGGERED_TICKS 2
84
80extern int tick_init_highres(void); 85extern int tick_init_highres(void);
81extern int tick_program_event(ktime_t expires, int force); 86extern int tick_program_event(ktime_t expires, int force);
82extern void tick_setup_sched_timer(void); 87extern void tick_setup_sched_timer(void);
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 0cf1c1453181..2079d6650532 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -1118,12 +1118,56 @@ static int __init skew_tick(char *str)
1118early_param("skew_tick", skew_tick); 1118early_param("skew_tick", skew_tick);
1119 1119
1120/** 1120/**
1121 * tick_set_quanta_type - get the quanta type as a boot option
1122 * Default is standard setup with ticks staggered over first
1123 * half of tick period.
1124 */
1125int quanta_type = LINUX_DEFAULT_TICKS;
1126static int __init tick_set_quanta_type(char *str)
1127{
1128 if (strcmp("aligned", str) == 0) {
1129 quanta_type = LITMUS_ALIGNED_TICKS;
1130 printk(KERN_INFO "LITMUS^RT: setting aligned quanta\n");
1131 }
1132 else if (strcmp("staggered", str) == 0) {
1133 quanta_type = LITMUS_STAGGERED_TICKS;
1134 printk(KERN_INFO "LITMUS^RT: setting staggered quanta\n");
1135 }
1136 return 1;
1137}
1138early_param("quanta=", tick_set_quanta_type);
1139
1140u64 cpu_stagger_offset(int cpu)
1141{
1142 u64 offset = 0;
1143 switch (quanta_type) {
1144 case LITMUS_ALIGNED_TICKS:
1145 offset = 0;
1146 break;
1147 case LITMUS_STAGGERED_TICKS:
1148 offset = ktime_to_ns(tick_period);
1149 do_div(offset, num_possible_cpus());
1150 offset *= cpu;
1151 break;
1152 default:
1153 /* default to Linux default behavior */
1154 if (sched_skew_tick) {
1155 offset = ktime_to_ns(tick_period) >> 1;
1156 do_div(offset, num_possible_cpus());
1157 offset *= cpu;
1158 }
1159 }
1160 return offset;
1161}
1162
1163/**
1121 * tick_setup_sched_timer - setup the tick emulation timer 1164 * tick_setup_sched_timer - setup the tick emulation timer
1122 */ 1165 */
1123void tick_setup_sched_timer(void) 1166void tick_setup_sched_timer(void)
1124{ 1167{
1125 struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); 1168 struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
1126 ktime_t now = ktime_get(); 1169 ktime_t now = ktime_get();
1170 u64 offset;
1127 1171
1128 /* 1172 /*
1129 * Emulate tick processing via per-CPU hrtimers: 1173 * Emulate tick processing via per-CPU hrtimers:
@@ -1134,13 +1178,11 @@ void tick_setup_sched_timer(void)
1134 /* Get the next period (per cpu) */ 1178 /* Get the next period (per cpu) */
1135 hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update()); 1179 hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update());
1136 1180
1137 /* Offset the tick to avert jiffies_lock contention. */ 1181 /* Offset must be set correctly to achieve desired quanta type. */
1138 if (sched_skew_tick) { 1182 offset = cpu_stagger_offset(smp_processor_id());
1139 u64 offset = ktime_to_ns(tick_period) >> 1; 1183
1140 do_div(offset, num_possible_cpus()); 1184 /* Add the correct offset to expiration time */
1141 offset *= smp_processor_id(); 1185 hrtimer_add_expires_ns(&ts->sched_timer, offset);
1142 hrtimer_add_expires_ns(&ts->sched_timer, offset);
1143 }
1144 1186
1145 for (;;) { 1187 for (;;) {
1146 hrtimer_forward(&ts->sched_timer, now, tick_period); 1188 hrtimer_forward(&ts->sched_timer, now, tick_period);