[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <2b98f7946cd0411ab588ce9b55c2f8e2@baidu.com>
Date: Tue, 8 Jul 2025 00:23:36 +0000
From: "Li,Rongqing" <lirongqing@...du.com>
To: Oleg Nesterov <oleg@...hat.com>, Peter Zijlstra <peterz@...radead.org>,
David Laight <david.laight.linux@...il.com>
CC: "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
"vschneid@...hat.com" <vschneid@...hat.com>, "mgorman@...e.de"
<mgorman@...e.de>, "bsegall@...gle.com" <bsegall@...gle.com>,
"rostedt@...dmis.org" <rostedt@...dmis.org>, "dietmar.eggemann@....com"
<dietmar.eggemann@....com>, "vincent.guittot@...aro.org"
<vincent.guittot@...aro.org>, "juri.lelli@...hat.com"
<juri.lelli@...hat.com>, "mingo@...hat.com" <mingo@...hat.com>
Subject: 答复: [????] Re: divide error in x86 and cputime
> non-x86 system maybe has same issue, once (stime + utime) overflows 64bit,
> mul_u64_u64_div_u64 from lib/math/div64.c maybe cause division by 0
>
Correct this, mul_u64_u64_div_u64(0x69f98da9ba980c00, 0xfffd213aabd74626, 0x009e00900) oflib/math/div64.c returns 0xffffffffffffffff
> so to cputime, could cputime_adjust() return stime if stime if stime + utime is
> overflow
>
> diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index
> 6dab4854..db0c273 100644
> --- a/kernel/sched/cputime.c
> +++ b/kernel/sched/cputime.c
> @@ -579,6 +579,10 @@ void cputime_adjust(struct task_cputime *curr, struct
> prev_cputime *prev,
> goto update;
> }
>
> + if (stime > (stime + utime)) {
> + goto update;
> + }
> +
> stime = mul_u64_u64_div_u64(stime, rtime, stime + utime);
> /*
> * Because mul_u64_u64_div_u64() can approximate on some
>
>
> Thanks
>
> -Li
>
>
> > Oleg.
> >
> > On 07/08, Oleg Nesterov wrote:
> > >
> > > On 07/07, Li,Rongqing wrote:
> > > >
> > > > [78250815.703847] divide error: 0000 [#1] PREEMPT SMP NOPTI
> > >
> > > ...
> > >
> > > > It caused by a process with many threads running very long, and
> > > > utime+stime overflowed 64bit, then cause the below div
> > > >
> > > > mul_u64_u64_div_u64(0x69f98da9ba980c00, 0xfffd213aabd74626,
> > > > 0x09e00900);
> > > >
> > > > I see the comments of mul_u64_u64_div_u64() say:
> > > >
> > > > Will generate an #DE when the result doesn't fit u64, could fix
> > > > with an __ex_table[] entry when it becomes an issu
> > > >
> > > > Seem __ex_table[] entry for div does not work ?
> > >
> > > Well, the current version doesn't have an __ex_table[] entry for div...
> > >
> > > I do not know what can/should we do in this case... Perhaps
> > >
> > > static inline u64 mul_u64_u64_div_u64(u64 a, u64 mul, u64 div)
> > > {
> > > int ok = 0;
> > > u64 q;
> > >
> > > asm ("mulq %3; 1: divq %4; movl $1,%1; 2:\n"
> > > _ASM_EXTABLE(1b, 2b)
> > > : "=a" (q), "+r" (ok)
> > > : "a" (a), "rm" (mul), "rm" (div)
> > > : "rdx");
> > >
> > > return ok ? q : -1ul;
> > > }
> > >
> > > ?
> > >
> > > Should return ULLONG_MAX on #DE.
> > >
> > > Oleg.
Powered by blists - more mailing lists