linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Linus Torvalds <torvalds@linux-foundation.org>
To: David Howells <dhowells@redhat.com>
Cc: Nicholas Piggin <npiggin@gmail.com>,
	Mateusz Guzik <mjguzik@gmail.com>,
	linux-arch <linux-arch@vger.kernel.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,
	Michael Ellerman <mpe@ellerman.id.au>,
	tony.luck@intel.com, viro@zeniv.linux.org.uk,
	linux-fsdevel@vger.kernel.org,
	Jan Glauber <jan.glauber@gmail.com>,
	linuxppc-dev <linuxppc-dev@lists.ozlabs.org>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>
Subject: Re: Memory transaction instructions
Date: Mon, 16 Jan 2023 08:59:16 -0800	[thread overview]
Message-ID: <CAHk-=whjFwzEq0u04=n=t7-kNJdX0HkAOjAMjmLXDDycJ+j9yQ@mail.gmail.com> (raw)
In-Reply-To: <1966767.1673878095@warthog.procyon.org.uk>

On Mon, Jan 16, 2023 at 6:08 AM David Howells <dhowells@redhat.com> wrote:
>
> I'm not sure how relevant it is to the topic, but I seem to remember you
> having a go at implementing spinlocks with x86_64 memory transaction
> instructions a while back.  Do you have any thoughts on whether these
> instructions are ever likely to become something we can use?

Nope.

Not only are they buggy, the actual cost of them was prohibitive too.

The only implementation I ever did was what then became 'lockref' (so
this was about a decade ago), and using transactional memory was
actually quite noticeably *slower* than just using a spinlock in the
common cases (particularly the uncontended case - which is actually
the common one by far, despite some benchmarks).

And while the argument could be that transactional memory has improved
in the last decade (narrator: "It hasn't"), the problem is actually
quite fundamental.

The whole "best case scenario" for transactional memory concept is
literally optimized and designed for the rare circumstance - the case
where you have contention, but where the locking part is basically an
idempotent operation (so "lock+unlock" ends up undoing each other and
can use shared cachelines rather than bouncing the cacheline).

And contention pretty much happens in one situation, and one situation
only: in a combination of (a) bad locking and (b) benchmarks.

And for the kernel, where we don't have bad locking, and where we
actually use fine-grained locks that are _near_ the data that we are
locking (the lockref of the dcache is obviously one example of that,
but the skbuff queue you mention is almost certainly exactly the same
situation): the lock is right by the data that the lock protects, and
the "shared lock cacheline" model simply does not work. You'll bounce
the data, and most likely you'll also touch the same lock cacheline
too.

I was quite excited about transactional memory, but have (obviously)
come to the conclusion that it was one of those "looks good in theory,
but is just garbage in reality".

So this isn't an "the x86 implementation was bad" issue. This is a
"transactional memory is a bad idea" situation. It complicates the
most important part of the core CPU (the memory pipeline) enormously,
and it doesn't actually really work.

Now, with that "transactional memory is garbage" in mind, let me just
mention that there are obviously other circumstances:

 (a) horrendously bad locking

If you have a single centralized lock, and you really have serious
contention on it in real life all the time (and not just under
microbenchmarks), and the data that gets touched is spread out all
over, and you simply cannot fix the locking, then all those
theoretical advantages of transactional memory can actually come into
play.

But again: even then, there's an absolutely huge cost to the memory
pipeline.  So that advantage really doesn't come free. Nobody has ever
gotten transactional memory to actually work well in real life. Not
Intel, not IBM with powerpc HTM.

That should tell you something. The hw complexity cost is very very real.

But Intel actually had some loads where TSX helped. I think it was SAP
HANA, and I really think that what you should take away from that is
that SAP HANA locking is likely horrible garbage inside. But maybe I'm
biased, and maybe SAP HANA is lovely, and maybe it just happened to
work really well for TSX. I've never actually looked at that load, but
if I were a betting man...

 (b) very *limited* transactions are probably a great idea

LL/SC is arguably a form of "transactional memory", just with a single
word. Now, I think atomics are generally usually better than LL/SC
when it really is just a single word (because most of the time,
"single word" also means "simple semantics", and while CMPXCHG loops
aren't lovely when the semantics are a bit more complex, it's actually
nice and portable and works at a higher level than assembler sequences
and as such is actually a *lot* better than LL/SC in practice).

But a "N-word LL/SC with forward progress guarantees" would be
objectively stronger than atomics, and would allow for doing low-level
data structures in ways that atomics don't. Doubly linked lists
together with a lock check would argue for "N" being ~5 memory
operations. So I do believe in potentially *limited* memory
transactions, when they can be made limited enough that you have

 (1) forward progress guarantees with no "separate fallback on
contention" garbage

 (2) can keep the hw implementation simple enough with just a store
buffer and an (architecturally) very limited number of cacheline
accesses that you can actually order in HW so that you don't have ABBA
situations.

But the generic kind of transactional memory that Intel tried with TSX
(and IBM with HTM) is pure garbage, and almost certainly always will
be.

And all of the above is obviously just my opinionated input on it. But
I just happen to be right.

                Linus

  parent reply	other threads:[~2023-01-16 17:28 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-12 23:36 lockref scalability on x86-64 vs cpu_relax Mateusz Guzik
2023-01-13  0:13 ` Linus Torvalds
2023-01-13  0:30   ` Luck, Tony
2023-01-13  0:45     ` Linus Torvalds
2023-01-13  7:55     ` ia64 removal (was: Re: lockref scalability on x86-64 vs cpu_relax) Ard Biesheuvel
2023-01-13 16:17       ` Luck, Tony
2023-01-13 20:49       ` Jessica Clarke
2023-01-13 21:03         ` Luck, Tony
2023-01-13 21:04           ` Jessica Clarke
2023-01-13 21:05       ` John Paul Adrian Glaubitz
2023-01-13 23:25         ` Ard Biesheuvel
2023-01-14 11:24           ` Sedat Dilek
2023-01-14 11:28             ` Sedat Dilek
2023-01-15  0:27               ` Matthew Wilcox
2023-01-15 12:04                 ` Sedat Dilek
2023-01-16  9:42                   ` John Paul Adrian Glaubitz
2023-01-16  9:41                 ` John Paul Adrian Glaubitz
2023-01-16 13:28                   ` Matthew Wilcox
2023-01-16  9:40               ` John Paul Adrian Glaubitz
2023-01-16  9:37             ` John Paul Adrian Glaubitz
2023-01-16  9:32           ` John Paul Adrian Glaubitz
2023-01-16 10:09             ` Ard Biesheuvel
2023-01-13  1:12   ` lockref scalability on x86-64 vs cpu_relax Mateusz Guzik
2023-01-13  4:08     ` Linus Torvalds
2023-01-13  9:46     ` Will Deacon
2023-01-13  3:20   ` Nicholas Piggin
2023-01-13  4:15     ` Linus Torvalds
2023-01-13  5:36       ` Nicholas Piggin
2023-01-16 14:08     ` Memory transaction instructions David Howells
2023-01-16 15:09       ` Matthew Wilcox
2023-01-16 16:59       ` Linus Torvalds [this message]
2023-01-18  9:05       ` David Howells
2023-01-19  1:41         ` Nicholas Piggin
2023-01-13 10:23   ` lockref scalability on x86-64 vs cpu_relax Peter Zijlstra
2023-01-13 18:44   ` [PATCH] lockref: stop doing cpu_relax in the cmpxchg loop Mateusz Guzik
2023-01-13 21:47     ` Luck, Tony
2023-01-13 23:31       ` Linus Torvalds

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAHk-=whjFwzEq0u04=n=t7-kNJdX0HkAOjAMjmLXDDycJ+j9yQ@mail.gmail.com' \
    --to=torvalds@linux-foundation.org \
    --cc=catalin.marinas@arm.com \
    --cc=dhowells@redhat.com \
    --cc=jan.glauber@gmail.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mjguzik@gmail.com \
    --cc=mpe@ellerman.id.au \
    --cc=npiggin@gmail.com \
    --cc=tony.luck@intel.com \
    --cc=viro@zeniv.linux.org.uk \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).