Messages in this thread | | | Subject | Re: [PATCH] sched: fair group: fix divide by zero | From | Peter Zijlstra <> | Date | Wed, 11 Jun 2008 09:15:47 +0200 |
| |
On Wed, 2008-06-11 at 15:12 +0800, Lai Jiangshan wrote: > I found a bug which can be reproduced by this way:(linux-2.6.26-rc5, x86-64) > (use 2^32, 2^33, ...., 2^63 as shares value)
I think the same thing to do is limit the shares value to something smaller instead of using an even more expensive divide.
> # mkdir /dev/cpuctl > # mount -t cgroup -o cpu cpuctl /dev/cpuctl > # cd /dev/cpuctl > # mkdir sub > # echo 0x8000000000000000 > sub/cpu.shares > # echo $$ > sub/tasks > oops here! divide by zero. > > This is because do_div() expects the 2th parameter to be 32 bits, > but unsigned long is 64 bits in x86_64. > > Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> > --- > diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c > index 08ae848..d3005b4 100644 > --- a/kernel/sched_fair.c > +++ b/kernel/sched_fair.c > @@ -368,7 +368,7 @@ static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se) > cfs_rq = cfs_rq_of(se); > > slice *= se->load.weight; > - do_div(slice, cfs_rq->load.weight); > + slice = div64_u64(slice, cfs_rq->load.weight); > } > > > @@ -399,7 +399,7 @@ static u64 sched_vslice_add(struct cfs_rq *cfs_rq, struct sched_entity *se) > weight += se->load.weight; > > vslice *= NICE_0_LOAD; > - do_div(vslice, weight); > + vslice = div64_u64(vslice, weight); > } > > return vslice; > >
| |