If I’m a crusader, where’s my cape?

Pete Zaitcev replied to my earlier post about misuse of atomic variables. I never really thought of myself as a crusader or as particularly quixotic, but I’ll respond to the technical content of Pete’s post. I think the disagreement was with my disparagement of the anti-pattern:

int x;

int foo(void)
{
        int y;

        spin_lock(&lock);
        y = x;
        spin_unlock(&lock);

        return y;
}

Pete is entirely correct that spin_lock() and spin_unlock() have full memory barriers; otherwise it would be impossible for anyone to use spinlocks correctly (and of course there’s still mmiowb() to trip you up when someone runs your driver on a big SGI machine).

However, I still think that using a spinlock around an assignment that’s atomic anyway is at best pretty silly. If you just need a memory barrier, then put an explicit mb() (or wmb() or rmb()) there, along with a fat comment about why you need to mess with memory barriers anyway.

Also, Pete is not entirely correct when he says that atomic operations lack memory barriers. All atomic operations that return a value (eg atomic_dec_and_test()) do have a full memory barrier, and if you want a barrier to go with an atomic operation that doesn’t return a value, such as atomic_inc(), the kernel does supply a full range of primitives such as smp_mb__after_atomic_inc(). The file Documentation/memory-barriers.txt in the kernel source tree explains all of this in excruciating detail.

In the end the cost of an atomic op is roughly the same as the cost of a spin_lock()/spin_unlock() pair (they both have to do one locked operation, and everything else is pretty much in the noise for all but the most performance criticial code). Spinlocks are usually easier to think about, so I recommend only using atomic_t when it fits perfectly, such as a reference count (and even then using struct kref is probably better if you can). I’ve found from doing code review that code using atomic_t almost always has bugs, and we don’t have any magic debugging tools to find them (the way we have CONFIG_PROVE_LOCKING, CONFIG_DEBUG_SPINLOCK_SLEEP and so on for locks).

By the way, what’s up with mark mazurek? His blog seems to be an exact copy taken from Pete’s blog feed, with the added bonus of adding a comment to the post in my blog that Pete linked to. There are no ads or really anything beyond an exact duplicate of Pete’s blog, so I can’t figure out what the angle is.

3 Responses to “If I’m a crusader, where’s my cape?”

  1. Pete Zaitcev says:

    Did you have to give your Google juice to a blog scrapper? Sheesh!

    Actually, I am mildly curious what his purpose is. It’s not a regular splog, because the site has no ads. Also, he seems to pursue me personally. When my Advogato blog was separate, he scrapped from there too. It is very odd.

    If I had my own hosting, I’d track it down with one-time poisoning, but it’s not possible when sitting on LJ.

  2. roland says:

    Good point about the Google juice. I just changed the link to “nofollow” so it should give no benefit.

    The internet can be strange.

  3. […] Roland’s Blog Linux hacker, recovering mathematician, former athlete « If I’m a crusader, where’s my cape? […]