Am 9/26/2024 um 8:16 AM schrieb Mathieu Desnoyers:
On 2024-09-25 15:20, Mathieu Desnoyers wrote:
[...]
static inline
bool same_ptr(void *a, void *b)
{
     asm goto (
         "cmpq %[a], %[b]\n\t"
         "jne %l[ne]\n\t"
         : : [a] "r" (a), [b] "r" (b)
         : : ne);
     return true;
ne:
     return false;
}

Based on the information provided in this email thread,
it appears the only concern when it comes to comparing a
pointer loaded by rcu_dereference() with another pointer
is the possibility of compiler optimizations.

In the specific case of hazard pointer hpref_hp_get(), this
function does both loads which are then compared with one
another. Therefore, it is not possible for the user to
provide a comparison value known at compile-time, except
in the unlikely scenario where the hazard pointer would
be const, which does not really make much sense.

Therefore, just using rcu_dereference() for the second
load should be fine.

Thanks,

Mathieu


No, the issue introduced by the compiler optimization (or by your original patch) is that the CPU can speculatively load from the first pointer as soon as it has completeled the load of that poitner:


node = ...
// t's value can be computed here, since the value of node is known
...
node2 = ...
if (node == node2) // just a control dependency, doesn't prevent speculatively loading node
   t = *node

if we can force the compiler's hand, it will generate this code which provides the necessary ordering at hardware level:

node = ...
// t can't be computed here since the value of node2 is not known here
...
node2 = ...
// t can be computed here
if (node == node2)
   t = *node2


Kind regards,

  jonas


Reply via email to