Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Feb 2019 13:50:49 -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:  <C42A56E5-63C8-41DC-B298-B43BFFB66064@yahoo.com>
In-Reply-To: <0A345E1F-7675-4B4B-8A74-ACD59E90E72F@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>

next in thread | previous in thread | raw e-mail | index | archive | help
[I left implicit that I was summarizing for x!=3D0.]

On 2019-Feb-28, at 13:46, Mark Millard <marklmi at yahoo.com> wrote:



> 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:

I forgot to indicate the context: when x!-0

> 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):
>=20
> 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



=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?C42A56E5-63C8-41DC-B298-B43BFFB66064>