History

sched: Prevent compiler from optimising the sched_avg_update() loop

GCC 4.4.1 on ARM has been observed to replace the while loop in sched_avg_update with a call to uldivmod, resulting in the following build failure at link-time: kernel/built-in.o: In function `sched_avg_update': kernel/sched.c:1261: undefined reference to `__aeabi_uldivmod' kernel/sched.c:1261: undefined reference to `__aeabi_uldivmod' make: *** [.tmp_vmlinux1] Error 1 This patch introduces a fake data hazard to the loop body to prevent the compiler optimising the loop away.

Will Deacon committed 16 years ago

Commit 0d98bb21 parent 3c937171 file · +6 −0Browse files

Showing the changes to kernel (1 of 1 file). Show all

Unified · Split

kernel/sched.c+6−0
@@ -1254,6 +1254,12 @@ static void sched_avg_update(struct rq *rq) · 1253 unmodified lines
1254 s64 period = sched_avg_period();1254 s64 period = sched_avg_period();
1255 1255
1256 while ((s64)(rq->clock - rq->age_stamp) > period) {1256 while ((s64)(rq->clock - rq->age_stamp) > period) {
1257 /*
1258 * Inline assembly required to prevent the compiler
1259 * optimising this loop into a divmod call.
1260 * See __iter_div_u64_rem() for another example of this.
1261 */
1262 asm("" : "+rm" (rq->age_stamp));
1257 rq->age_stamp += period;1263 rq->age_stamp += period;
1258 rq->rt_avg /= 2;1264 rq->rt_avg /= 2;
1259 }1265 }