On Thu, Aug 28, 2025 at 05:35:26PM -0700, Linus Torvalds wrote: > On Thu, 28 Aug 2025 at 17:11, Al Viro <viro@xxxxxxxxxxxxxxxxxx> wrote: > > > > What I want to avoid is compiler seeing something like > > (unsigned long)READ_ONCE(m->mnt_pprev_for_sb) & 1 > > and going "that thing is a pointer to struct mount *, either the address > > is even or it's an undefined behaviour and I can do whatever I want > > anyway; optimize it to 0". > > Have you actually seen that? Because if some compiler does this, we > have tons of other places that will hit this, and we'll need to try to > figure out some generic solution, or - more likely - just disable said > compiler "optimization". list_bl.h being an obvious victim... OK, convinced. No, I hadn't seen that, and I agree that we'll get some very visible breakage if that ever happens. Anyway, I think I've come up with a trick that would be proof against that kind of idiocy: struct mount *__aligned(1) *mnt_pprev_for_sb; IOW, tell compiler that this member contains a pointer to a possibly unaligned object containing a pointer to struct mount. Since the member is declared as pointer to unaligned object, compiler is not allowed to make any assumptions about the LSB of its value. For any type T, we are fine with T __aligned(1) *p; ... T *q = p; and as long as the value of p is actually aligned, no nasal daemons should fly. Since we never dereference them directly ('add' doesn't dereference them at all, 'del' copies to local struct mount ** and dereferences that), all generated memory accesses will be aligned ones. Since the only values we'll ever assign to that member will be addresses of normally aligned objects, we should be fine. Sure, __attribute__((__aligned__(...))) is not standard, but AFAICS we should not step into any UB in a compiler implementing it... Replacements for the 59..62 in followups (I've reordered them - easier that way).