Am 9/30/2024 um 6:43 PM schrieb Alan Stern:
On Mon, Sep 30, 2024 at 01:26:53PM +0200, Jonas Oberhauser wrote:
Am 9/28/2024 um 4:49 PM schrieb Alan Stern:
On Sat, Sep 28, 2024 at 09:51:27AM -0400, Mathieu Desnoyers wrote:
Compiler CSE and SSA GVN optimizations can cause the address dependency
of addresses returned by rcu_dereference to be lost when comparing those
pointers with either constants or previously loaded pointers.
Introduce ptr_eq() to compare two addresses while preserving the address
dependencies for later use of the address. It should be used when
comparing an address returned by rcu_dereference().
This is needed to prevent the compiler CSE and SSA GVN optimizations
from replacing the registers holding @a or @b based on their
"Replacing" isn't the right word. What the compiler does is use one
rather than the other. Furthermore, the compiler can play these games
even with values that aren't in registers.
You should just say: "... from using @a (or @b) in places where the
source refers to @b (or @a) (based on the fact that after the
comparison, the two are known to be equal), which does not ..."
I should also point out that it is not enough to prevent the compiler from
using @a instead of @b.
It must also be prevented from assigning @b=@a, which it is often allowed to
do after finding @a==@b.
Wouldn't that be a bug?
That's why I said that it is often allowed to do it. In your case it
wouldn't, but it is often possible when a and b are non-atomic &
non-volatile (and haven't escaped, and I believe sometimes even then).
It happens for example here with GCC 14.1.0 -O3:
int fct_hide(void)
{
int *a, *b;
do {
a = READ_ONCE(p);
asm volatile ("" : : : "memory");
b = READ_ONCE(p);
} while (a != b);
OPTIMIZER_HIDE_VAR(b);
return *b;
}
ldr r1, [r2]
ldr r3, [r2]
cmp r1, r3
bne .L6
mov r3, r1 // nay...
ldr r0, [r3] // yay!
bx lr
Have fun,
jonas