Am 9/25/2024 um 8:35 AM schrieb Mathieu Desnoyers:
On 2024-09-25 07:57, Jonas Oberhauser wrote:
Hi Mathieu,
I haven't read your code in detail but it seems to me you have an ABA
bug: as I explained elsewhere, you could read the same pointer after
ABA but you don't synchronize with the newer store that gave you
node2, leaving you to speculatively read stale values through *ctx->hp.
(I am assuming here that ctx->hp is essentially an out parameter used
to let the caller know which node got protected).
The following change should fix it:
cmm_barrier();
- node2 = uatomic_load(node_p, CMM_RELAXED); /* Load A */
+ node2 = rcu_dereference(*node_p); /* Load A */
I don't think this fixes it, because IIRC rcu_dereference relies on the
address dependency (which we don't have here) to provide ordering.
I would recommend either:
- ctx->hp = node;
+ ctx->hp = node2;
which fixes the problem under the perhaps too weak assumption that the
compiler doesn't use its knowledge that node==node2 to just undo this
fix, or more strictly,
+ ctx->hp = READ_ONCE(node2);
which I believe makes sure that the value of node2 is used.
Alternatively you could always use an acquire load.
Best wishes,
jonas