Date: Sun, 17 Feb 2002 12:38:01 -0800 (PST) From: Matthew Dillon <dillon@apollo.backplane.com> To: Poul-Henning Kamp <phk@critter.freebsd.dk> Cc: Bruce Evans <bde@zeta.org.au>, freebsd-current@FreeBSD.ORG Subject: Success! Sorta! (was Re: 'microuptime() went backwards ...' using ACPI timer. Shouldn't that be impossible? ) Message-ID: <200202172038.g1HKc1891121@apollo.backplane.com> References: <5781.1013977327@critter.freebsd.dk>
next in thread | previous in thread | raw e-mail | index | archive | help
:Bruce's patch amounts to a retry if the current timecounter was updated
:while we were calculating time. It is a bit more defensive than it
:needs to be and generally pessimizes the timecounters elegant lockless
:design a fair bit, but it is still much better than slamming a mutex
:around the entire clock code.
:
:If this patch cures the PIIX problem, something I'm not at all convinced
:about, it should go in, if not only the comment should go in.
:
:Poul-Henning
:
:--
:Poul-Henning Kamp | UNIX since Zilog Zeus 3.20
Ok, I've tested Bruce's patch and it appeaars to mostly solve the problem.
I no longer get 'microuptime ... backwards' errors on a -current SMP
box.
However, I think to be complete we need to make it even less elegant.
The TC module is only flip-flopping between two time counters, which
means that it can flip-flop twice and the test will not work. We need
a generation count on the timecounter as well:
do {
tc = timecounter;
gen = tc->tc_generation;
*bt = tc->tc_offset;
bintime_addx(bt, tc->tc_scale * tco_delta(tc));
} while (tc != timecounter || tc->tc_generation != gen);
There is also an issue on non-i386 machines. The timecounter swapping
code requires a memory synchronization point after updating the
contents of the new timecounter but before setting the 'timecounter' global
to the new timecounter. If this is not done, non-i386 machines running
SMP may see the new timecounter structure but access pre-updated values
from it.
(i386 boxes do not have this problem because writes are ordered so the
inherent synchronication point at the end of the timer interrupt is
enough).
Is there a memory synchronization point macro available?
-Matt
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200202172038.g1HKc1891121>
