aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLai Jiangshan <laijs@cn.fujitsu.com>2008-06-12 04:43:07 -0400
committerIngo Molnar <mingo@elte.hu>2008-06-12 08:29:54 -0400
commit7a232e0350940d2664f4de5cc3f0f443bae5062d (patch)
treebb91a53faab7bf6e92df127f8bdb2225cf808925
parent2e084786f6fe052274f1dfa7c675fe4a02cacd6e (diff)
sched: 64-bit: fix arithmetics overflow
(overflow means weight >= 2^32 here, because inv_weigh = 2^32/weight) A weight of a cfs_rq is the sum of weights of which entities are queued on this cfs_rq, so it will overflow when there are too many entities. Although, overflow occurs very rarely, but it break fairness when it occurs. 64-bits systems have more memory than 32-bit systems and 64-bit systems can create more process usually, so overflow may occur more frequently. This patch guarantees fairness when overflow happens on 64-bit systems. Thanks to the optimization of compiler, it changes nothing on 32-bit. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--kernel/sched.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 6c1ecbdc0db9..eaf6751e7612 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1340,8 +1340,13 @@ calc_delta_mine(unsigned long delta_exec, unsigned long weight,
1340{ 1340{
1341 u64 tmp; 1341 u64 tmp;
1342 1342
1343 if (!lw->inv_weight) 1343 if (!lw->inv_weight) {
1344 lw->inv_weight = 1 + (WMULT_CONST-lw->weight/2)/(lw->weight+1); 1344 if (BITS_PER_LONG > 32 && unlikely(lw->weight >= WMULT_CONST))
1345 lw->inv_weight = 1;
1346 else
1347 lw->inv_weight = 1 + (WMULT_CONST-lw->weight/2)
1348 / (lw->weight+1);
1349 }
1345 1350
1346 tmp = (u64)delta_exec * weight; 1351 tmp = (u64)delta_exec * weight;
1347 /* 1352 /*