]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
sched: 64-bit: fix arithmetics overflow
authorLai Jiangshan <laijs@cn.fujitsu.com>
Thu, 12 Jun 2008 08:43:07 +0000 (16:43 +0800)
committerIngo Molnar <mingo@elte.hu>
Thu, 12 Jun 2008 12:29:54 +0000 (14:29 +0200)
(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>
kernel/sched.c

index 6c1ecbdc0db9941ffa7c5698761e71aa36381009..eaf6751e7612cbc5167865c8c1e4e929ff32ca5a 100644 (file)
@@ -1340,8 +1340,13 @@ calc_delta_mine(unsigned long delta_exec, unsigned long weight,
 {
        u64 tmp;
 
-       if (!lw->inv_weight)
-               lw->inv_weight = 1 + (WMULT_CONST-lw->weight/2)/(lw->weight+1);
+       if (!lw->inv_weight) {
+               if (BITS_PER_LONG > 32 && unlikely(lw->weight >= WMULT_CONST))
+                       lw->inv_weight = 1;
+               else
+                       lw->inv_weight = 1 + (WMULT_CONST-lw->weight/2)
+                               / (lw->weight+1);
+       }
 
        tmp = (u64)delta_exec * weight;
        /*