On 25/10/2026 10:50, Konstantin Ananyev wrote:
       /* in use, busy wait till current RX/TX iteration is finished */
        if ((puse & BPF_ETH_CBI_INUSE) != 0) {
                RTE_WAIT_UNTIL_MASKED((__rte_atomic uint32_t *)(uintptr_t)&cbi->use,                         UINT32_MAX, !=, puse, rte_memory_order_acquire);
        }

Here, we are waiting when 'puse' will become not equal to 'cbi->use'.
So, any value except current puse is good.

If you look a the sequence diagram, there is no way to arrive here without the callback being removed and `cb` cleared in the DP thread, no matter how you move the arrows around.  So the DP thread will increment `use` once to make it even, and then will never ever reach the callback or increment anything again. We allow any value except current puse, but there are never any values except the current puse and the one after it. It's just these two values we can possibly see.

DP can (and most likely will) call rx/tx_burst again.
Just to give you an example:
--- DP thread:
cbi->use = 1;
                         --- CP thread:
                            read cbi->use (1)
By this time the callback is removed and `cb` is cleared.

from CP thread perspective:
 a) bc->cb is removed from ethdev callback list
 b) bc->cb = NULL
But there is no guarantee that DP thread will see these changes till next
bpf_eth_cbi_inuse()->rte_atomic_thread_fence(rte_memory_order_seq_cst);
So it can still (at least once) invoke bpf callback and read and update cbi->use.

Thinking about that once again - it seems that could happen only once
(i.e. in that example CP thread will see just one of {1,2,3,4} after that point.
So I probably was too pessimistic about 'live-lock'.
But anyway, I don't see any point to change existing code to what you propose (boolean value).
From my perspective it doesn't make it safer (or faster) in any way.

--DP thread:
cbi->use = 2;
...
next rx burst:
cbi->use = 3;
How did we reach hear if `cb` is NULL?
                read cbi->use (3)

So CP sees an odd value (3), but it is ok to proceed, as previoud RX iteration (quiscent period) had already finished,
and in new one rx_burst will not see removed call-back.

Reply via email to