]>
Commit | Line | Data |
---|---|---|
45426b3c GKH |
1 | From 0d98bb2656e9bd2dfda2d089db1fe1dbdab41504 Mon Sep 17 00:00:00 2001 |
2 | From: Will Deacon <will.deacon@arm.com> | |
3 | Date: Mon, 24 May 2010 12:11:43 -0700 | |
4 | Subject: sched: Prevent compiler from optimising the sched_avg_update() loop | |
5 | ||
6 | From: Will Deacon <will.deacon@arm.com> | |
7 | ||
8 | commit 0d98bb2656e9bd2dfda2d089db1fe1dbdab41504 upstream. | |
9 | ||
10 | GCC 4.4.1 on ARM has been observed to replace the while loop in | |
11 | sched_avg_update with a call to uldivmod, resulting in the | |
12 | following build failure at link-time: | |
13 | ||
14 | kernel/built-in.o: In function `sched_avg_update': | |
15 | kernel/sched.c:1261: undefined reference to `__aeabi_uldivmod' | |
16 | kernel/sched.c:1261: undefined reference to `__aeabi_uldivmod' | |
17 | make: *** [.tmp_vmlinux1] Error 1 | |
18 | ||
19 | This patch introduces a fake data hazard to the loop body to | |
20 | prevent the compiler optimising the loop away. | |
21 | ||
22 | Signed-off-by: Will Deacon <will.deacon@arm.com> | |
23 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | |
24 | Acked-by: Peter Zijlstra <peterz@infradead.org> | |
25 | Cc: Catalin Marinas <catalin.marinas@arm.com> | |
26 | Cc: Russell King <rmk@arm.linux.org.uk> | |
27 | Cc: Linus Torvalds <torvalds@linux-foundation.org> | |
28 | Signed-off-by: Ingo Molnar <mingo@elte.hu> | |
29 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
30 | ||
31 | --- | |
32 | kernel/sched.c | 6 ++++++ | |
33 | 1 file changed, 6 insertions(+) | |
34 | ||
35 | --- a/kernel/sched.c | |
36 | +++ b/kernel/sched.c | |
37 | @@ -1261,6 +1261,12 @@ static void sched_avg_update(struct rq * | |
38 | s64 period = sched_avg_period(); | |
39 | ||
40 | while ((s64)(rq->clock - rq->age_stamp) > period) { | |
41 | + /* | |
42 | + * Inline assembly required to prevent the compiler | |
43 | + * optimising this loop into a divmod call. | |
44 | + * See __iter_div_u64_rem() for another example of this. | |
45 | + */ | |
46 | + asm("" : "+rm" (rq->age_stamp)); | |
47 | rq->age_stamp += period; | |
48 | rq->rt_avg /= 2; | |
49 | } |