diff options
author | Felipe Cerqueira <felipec@mpi-sws.org> | 2013-02-12 11:50:12 -0500 |
---|---|---|
committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2013-08-07 03:46:41 -0400 |
commit | 05ad941dfa83599208ee11b67c49ad54c4f3b78a (patch) | |
tree | 6c28687378286d6777c2980930ef487243d8fc8c | |
parent | 01a0a30a003019092e7748049a03bb5cfd0ab918 (diff) |
Add quantum aligment code
Enable staggered ticks for PD^2.
-rw-r--r-- | include/linux/tick.h | 5 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 56 |
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); | |||
77 | extern struct tick_device *tick_get_device(int cpu); | 77 | extern 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 | |||
80 | extern int tick_init_highres(void); | 85 | extern int tick_init_highres(void); |
81 | extern int tick_program_event(ktime_t expires, int force); | 86 | extern int tick_program_event(ktime_t expires, int force); |
82 | extern void tick_setup_sched_timer(void); | 87 | extern 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) | |||
1118 | early_param("skew_tick", skew_tick); | 1118 | early_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 | */ | ||
1125 | int quanta_type = LINUX_DEFAULT_TICKS; | ||
1126 | static 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 | } | ||
1138 | early_param("quanta=", tick_set_quanta_type); | ||
1139 | |||
1140 | u64 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 | */ |
1123 | void tick_setup_sched_timer(void) | 1166 | void 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); |