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.
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -1254,6 +1254,12 @@ static void sched_avg_update(struct rq *rq) · 1253 unmodified lines | ||
| 1254 | 1254 | s64 period = sched_avg_period(); |
| 1255 | 1255 | |
| 1256 | 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 | 1263 | rq->age_stamp += period; |
| 1258 | 1264 | rq->rt_avg /= 2; |
| 1259 | 1265 | } |