Date: Thu, 28 Feb 2019 14:23:26 -0800 From: Mark Millard <marklmi@yahoo.com> To: Konstantin Belousov <kib@freebsd.org> Cc: freebsd-hackers Hackers <freebsd-hackers@freebsd.org>, FreeBSD PowerPC ML <freebsd-ppc@freebsd.org> Subject: Re: powerpc64 head -r344018 stuck sleeping problems: th->th_scale * tc_delta(th) overflows unsigned 64 bits sometimes Message-ID: <5C2FABEC-C56A-4153-A3FD-D5E1D54F1F6E@yahoo.com> In-Reply-To: <C42A56E5-63C8-41DC-B298-B43BFFB66064@yahoo.com> References: <D3D7E9F4-9A5E-4320-B3C8-EC5CEF4A2764@yahoo.com> <20190228145542.GT2420@kib.kiev.ua> <20190228150811.GU2420@kib.kiev.ua> <0A345E1F-7675-4B4B-8A74-ACD59E90E72F@yahoo.com> <C42A56E5-63C8-41DC-B298-B43BFFB66064@yahoo.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[I was distracted and made a stupid mistake. Sorry for the noise.] On 2019-Feb-28, at 13:50, Mark Millard <marklmi@yahoo.com> wrote: > [I left implicit that I was summarizing for x!=3D0.] >=20 > On 2019-Feb-28, at 13:46, Mark Millard <marklmi at yahoo.com> wrote: >=20 >=20 >=20 >> On 2019-Feb-28, at 07:08, Konstantin Belousov <kib at freebsd.org> = wrote: >>=20 >>> On Thu, Feb 28, 2019 at 04:55:42PM +0200, Konstantin Belousov wrote: >>>> On Thu, Feb 28, 2019 at 05:06:23AM -0800, Mark Millard via = freebsd-ppc wrote: >>>>> . . . >>>>=20 >>>> . . . >>>=20 >>> Of course I botched the formula, please try this instead: >>>=20 >>> diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c >>> index 2656fb4d22f..fdd4f4f6a52 100644 >>> --- a/sys/kern/kern_tc.c >>> +++ b/sys/kern/kern_tc.c >>> @@ -355,13 +355,22 @@ void >>> binuptime(struct bintime *bt) >>> { >>> struct timehands *th; >>> - u_int gen; >>> + uint64_t scale, x; >>> + u_int delta, gen; >>>=20 >>> do { >>> th =3D timehands; >>> gen =3D atomic_load_acq_int(&th->th_generation); >>> *bt =3D th->th_offset; >>> - bintime_addx(bt, th->th_scale * tc_delta(th)); >>> + scale =3D th->th_scale; >>> + delta =3D tc_delta(th); >>> + if (fls(scale) + fls(delta) > 63) { >>> + x =3D (scale >> 32) * delta; >>> + scale &=3D UINT_MAX; >>=20 >> The following two lines confuse me overall: >>=20 >>> + bt->sec +=3D x >> 32; >>> + bintime_addx(bt, x << 32); >>=20 >> bintime_addx does: >>=20 >> static __inline void >> bintime_addx(struct bintime *_bt, uint64_t _x) >> { >> uint64_t _u; >>=20 >> _u =3D _bt->frac; >> _bt->frac +=3D _x; >> if (_u > _bt->frac) >> _bt->sec++; >> } >>=20 >> So I'd expect: >=20 > I forgot to indicate the context: when x!-0 >=20 >> bintime_addx(bt, x << 32) >>=20 >> to find _u > _bt->frac and to also do _bt->sec++ . >> So overall (as a means of summarizing for >> bt->sec): How I got _u > _bt->frac for that call in general when the call's (x<<32) !=3D 0 I do not know. So ignore my stupid, mistaken questions. >> bt->sec +=3D (x >> 32) + 1; >>=20 >> Is that the intent? >>=20 >>=20 >>> + } >>> + bintime_addx(bt, scale * delta); >>> atomic_thread_fence_acq(); >>> } while (gen =3D=3D 0 || gen !=3D th->th_generation); >>> } >>> @@ -388,13 +397,22 @@ void >>> bintime(struct bintime *bt) >>> { >>> struct timehands *th; >>> - u_int gen; >>> + uint64_t scale, x; >>> + u_int delta, gen; >>>=20 >>> do { >>> th =3D timehands; >>> gen =3D atomic_load_acq_int(&th->th_generation); >>> *bt =3D th->th_bintime; >>> - bintime_addx(bt, th->th_scale * tc_delta(th)); >>> + scale =3D th->th_scale; >>> + delta =3D tc_delta(th); >>> + if (fls(scale) + fls(delta) > 63) { >>> + x =3D (scale >> 32) * delta; >>> + scale &=3D UINT_MAX; >>=20 >> The same for the below two lines: >>=20 >>> + bt->sec +=3D x >> 32; >>> + bintime_addx(bt, x << 32); >>=20 >>=20 >>> + } >>> + bintime_addx(bt, scale * delta); >>> atomic_thread_fence_acq(); >>> } while (gen =3D=3D 0 || gen !=3D th->th_generation); >>> } >>=20 >=20 >=20 =3D=3D=3D Mark Millard marklmi at yahoo.com ( dsl-only.net went away in early 2018-Mar)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5C2FABEC-C56A-4153-A3FD-D5E1D54F1F6E>