Re: [PATCH v2] rust: page: add byte-wise atomic memory copy methods

From: Alice Ryhl

Date: Wed Feb 18 2026 - 04:31:29 EST


On Wed, Feb 18, 2026 at 09:37:54AM +0100, Peter Zijlstra wrote:
> On Tue, Feb 17, 2026 at 11:39:18PM +0000, Gary Guo wrote:
>
> > >> Are we really good? Consider this code:
> > >>
> > >> bool is_valid(struct foo *val)
> > >> {
> > >> // for the sake of example
> > >> return val->my_field != 0;
> > >> }
> > >>
> > >> struct foo val;
> > >>
> > >> void *ptr = kmap_local_page(p1);
> > >> memcpy(ptr, val, sizeof(struct foo));
> > >> kunmap_local(p);
> > >> barrier();
> > >> if (is_valid(&val)) {
> > >> // use val
> > >> }
> > >>
> > >> optimize it into this first:
> > >>
> > >> struct foo val;
> > >> int my_field_copy;
> > >>
> > >> void *ptr = kmap_local_page(p1);
> > >> memcpy(ptr, val, sizeof(struct foo));
> > >> my_field_copy = val->my_field;
> > >> kunmap_local(p);
> > >> barrier();
> > >> if (my_field_copy != 0) {
> > >> // use val
> > >> }
> > >>
> > >> then optimize it into:
> > >>
> > >> struct foo val;
> > >> int my_field_copy;
> > >>
> > >> void *ptr = kmap_local_page(p1);
> > >> memcpy(ptr, val, sizeof(struct foo));
> > >> my_field_copy = ((struct foo *) ptr)->my_field;
> > >> kunmap_local(p);
> > >> barrier();
> > >> if (my_field_copy != 0) {
> > >> // use val
> > >> }
> > >
> > > I don;t think this is allowed. You're lifting the load over the
> > > barrier(), that is invalid.
> >
> > This is allowed. Compilers perform escape analysis and find out that
> > "val" does not escape the function and therefore nothing can change "val".
> >
> > A simple example to demonstrate this effect is that
> >
> > int x = 0;
> > x = 1;
> > barrier();
> > do_something(x);
> >
> > is happily optimized into
> >
> > barrier();
> > do_something(1);
> >
> > by both GCC and Clang. The fact that the local variable here is a struct and
> > memcpy is used to assign the value here does not make a fundamental difference.
> >
> > barrier() does nothing to local variables if pointers to them do not escape the
> > local function.
>
> So how do we stop the compiler from doing this? Because I'm thinking
> there's quite a bit of code that would be broken if this were done.
>
> Must we really go write things like:
>
> struct foo val, *ptr;
>
> ptr = kmap_local_page(page);
> memcpy(ptr, val, sizeof(val));
> kunmap_local(ptr);
>
> ptr = RELOC_HIDE(&val, 0);
>
> if (ptr->field) {
> ...
> }
>
> That seems 'unfortunate'. It basically means we must never use local
> stack for copies or somesuch.

No I don't think RELOC_HIDE is what you want to be using here.

The way to stop the compiler from doing this is to ensure that, in
LLVM's eyes, the memcpy is either a volatile memcpy, an atomic memcpy,
or an opaque function call. According to Gary's reply to my email on V3,
it sounds like an explicit call to memcpy like this apparently falls into
opaque function call, so it should be okay.

Anyway, that's why using Rust's copy_nonoverlapping() isn't okay here.
It emits a non-volatile non-atomic LLVM memcpy intrinsic, which permits
these optimizations that we don't want in this case. By calling
bindings::memcpy(), it falls into the opaque function call category
instead, which fixes the problem.

Alice