Messages in this thread | | | Date | Fri, 26 Nov 1999 02:40:33 +0100 (CET) | From | Ingo Molnar <> | Subject | Re: spin_unlock optimization(i386) |
| |
On Thu, 25 Nov 1999, Linus Torvalds wrote:
> I disagree. > > Without any speculative reads, you don't need serialization. It would be > enough that "lock" just guaranteed that the operation was done atomically. > > But I bet that it's more than the atomicity. The serialization is actually > needed to make sure that no reads speculate "upwards" to before the locked > intruction.
hm. On the other hand it could just be pure (release management) paranoia to not have to deal with speculative read conflicts during LOCK-ed operations.
Erich says that Intel gets the other cases right and guarantees Processor Ordering (which means causality for all operations including reads), then i cannot possibly see how this is consistent with giving noncausal memory values to reordered reads.
> And the reason we don't need serialization on the unlock side (where > atomicity is simpleto guarantee, because it's a single operation) is > because Intel doesn't ever move reads "downwards" past a write, so the > single write basically does act as a complete ordering downwards.
yep, i agree that for the spin_unlock() trick it would be sufficient to have the 'writes never pass reads' rule (still a Weakly Ordered memory model because reads would still be allowed to pass reads and pass writes upwards). In fact my smp-2.3.30-A1 patch was done assuming this rule.
but with the Processor Ordering memory model we do not need any explicit barriers at all (apart from the compiler barrier). We need atomicity for the lock, and a compiler barrier for the unlock, but nothing else.
> And THAT is the assymetry: intel can and will re-order > > write A > read B
yep. I completely understand what you mean.
> If Intel only needed to be atomic, doing the "lock btsl" would not need to > take 22 cycles. The cost comes from being a syncronization barrier, which > is needed to avoid the re-ordering that intel _will_ do.
if i was Intel and had the instruction traces they have, maybe i'd have been a wimp as well :) Making LOCK-ed instruction go straight through via just relying on a (hypotetical) internal 'conflict prevention' mechanizm would definitely have been a feat, and would have triggered all the remaining bugs ;)
> But note that a single write will NOT act as a "complete memory barrier" > as implied by the Linux "mb()" macro. The single write will make sure that > a read does now move downwards _outside_ the lock (which is all that a > spinlock cares about) - the single nonsynchronizing write does not > guarantee that reads won't move upwards _into_ the critical region. > > (moving reads _into_ the critical region is fine - it makes the critical > region "bigger", but as the reason for moving the reads up is to allow > more parallellism, it doesn't actually make the critical region any > slower, which is all that we care about - and it does speed up the exit > from the protected region).
ok. I think we can actually prove wether reads can even execute noncausal. Lets consider the following code:
CPU0 CPU1
volatile int i, __fill[8], j; int a, b;
i = j = 0;
for (;;) { for (;;) { i++; a = i; j++; b = j; } if (a < b) BUG() }
(i and j are shared common variables on different cachelines, a and b are local ones)
if your theory is true, then 'BUG()' should trigger sooner or later, correct?
Ingo
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |