Re: [WIP 0/3] Memory model and atomic API in Rust

From: Kent Overstreet
Date: Mon Mar 25 2024 - 14:59:58 EST


On Mon, Mar 25, 2024 at 10:44:43AM -0700, Linus Torvalds wrote:
> On Mon, 25 Mar 2024 at 06:57, Philipp Stanner <pstanner@xxxxxxxxxx> wrote:
> >
> > On Fri, 2024-03-22 at 17:36 -0700, Linus Torvalds wrote:
> > >
> > > It's kind of like our "volatile" usage. If you read the C (and C++)
> > > standards, you'll find that you should use "volatile" on data types.
> > > That's almost *never* what the kernel does. The kernel uses
> > > "volatile"
> > > in _code_ (ie READ_ONCE() etc), and uses it by casting etc.
> > >
> > > Compiler people don't tend to really like those kinds of things.
> >
> > Just for my understanding: Why don't they like it?
>
> So I actually think most compiler people are perfectly fine with the
> kernel model of mostly doing 'volatile' not on the data structures
> themselves, but as accesses through casts.
>
> It's very traditional C, and there's actually nothing particularly odd
> about it. Not even from a compiler standpoint.
>
> In fact, I personally will argue that it is fundamentally wrong to
> think that the underlying data has to be volatile. A variable may be
> entirely stable in some cases (ie locks held), but not in others.
>
> So it's not the *variable* (aka "object") that is 'volatile', it's the
> *context* that makes a particular access volatile.
>
> That explains why the kernel has basically zero actual volatile
> objects, and 99% of all volatile accesses are done through accessor
> functions that use a cast to mark a particular access volatile.
>
> But I've had negative comments from compiler people who read the
> standards as language lawyers (which honestly, I despise - it's always
> possible to try to argue what the meaning of some wording is), and
> particularly C++ people used to be very very antsy about "volatile".
>
> They had some truly _serious_ problems with volatile.
>
> The C++ people spent absolutely insane amounts of time arguing about
> "volatile objects" vs "accesses", and how an access through a cast
> didn't make the underlying object volatile etc.

To be fair, "volatile" dates from an era when we didn't have the haziest
understanding of what a working memory model for C would look like or
why we'd even want one.

(Someone might want to think about depracating volatile on objects and
adding compiler flag to disable it; I suspect it'd be a useful cleanup
for the compiler guys if they could get rid of it.)

The way the kernel uses volatile in e.g. READ_ONCE() is fully in line
with modern thinking, just done with the tools available at the time. A
more modern version would be just

__atomic_load_n(ptr, __ATOMIC_RELAXED)

Except C atomics only support pointer and integer types, READ_ONCE()
supports anything up to machine word size - that's something the C
people need to fix.