svn commit: r219646 - head/sys/x86/isa

Bruce Evans brde at optusnet.com.au
Wed Mar 16 07:04:14 UTC 2011


On Tue, 15 Mar 2011, Jung-uk Kim wrote:

> On Tuesday 15 March 2011 03:51 pm, John Baldwin wrote:
>> On Tuesday, March 15, 2011 3:26:11 pm Jung-uk Kim wrote:
>>> Now don't you think we should really kill delay by TSC? ;-)
>>
>> Delay by TSC fixed known deadlocks with the i8254 based DELAY() due
>> to the use of locks.  Be careful that you don't re-introduce old
>> bugs.
>
> Yeah, that's perfectly understood.

I don't understand it.  I don't know of any deadlocks except the ones
in ddb that I fixed, and there were deadlocks, they can't have been
fixed by using the TSC, since the TSC is not always available.  It
is not even always available on systems that have a P-state invariant
TSC synchronized across all CPUs, since it is not initialized early,
so the old deadlock avoidance is still needed.  In fact, I found the
deadlock using ddb to debug TSC initialization which used the i8254
(not via DELAY()) for calibrating the TSC frequency.

>> Also, you can use a TSC for DELAY() in cases when it is not safe to
>> use it for the timecounter (if it is not in sync across cores, but
>> is used in a machine with invariant TSCs or where the user knows
>> they won't ever throttle it). Modern Intel CPUs all have invariant
>> TSCs that are more or less in sync across cores, and we should
>> certainly still use the TSC for DELAY() in that case. Even if they
>> aren't in sync (so we can't use it for the timecounter) we should
>> still use the TSC if they are invariant as it is far cheaper than
>> anything else.
>
> That, too, is well understood.  You know I added tsc_is_invariant
> myself. :-)

"1: [pause;] decl %eax; jne 1b" in a loop works just as well as rdtsc
in a loop if the TSC is _not_ P-state invariant.  Both break similarly
if the TSC frequency changes.  You have to change the loop count if
the frequency changes, but it is hard to tell if this is necessary.
Telling if it is necessary requires reading a real hardware timer to
recalibrate occasionally from within the loop and without, and the
timer read from within the loop gives the same locking complications
that you are trying to avoid.

> However, why do we need cheaper DELAY() when we trying to "delay"
> something with it?

kib mentioned bus activity.  "1: decl %eax; jne 1b" doesn't have that.
I wonder if rdtsc has it.  Phenom has much slower rdtsc than Athlon
to help make it P-state invariant.  Does this involve bus activity?
What does "pause" do in a loop that is only accessing registers?

Bruce


More information about the svn-src-all mailing list