[PATCH v2 5/9] bpf: simplify callback inuse tracking to boolean flag

Konstantin Ananyev konstantin.v.ananyev at yandex.ru
Sun Oct 25 11:50:58 CET 2026



25.10.2026 10:24, Marat Khalili пишет:
>
> On 25/10/2026 07:40, Konstantin Ananyev wrote:
>>> On 19/10/2026 21:50, Konstantin Ananyev wrote:
>>>>> The even/odd usage counter semantics in struct bpf_eth_cbi was
>>>>> originally used to detect when in-flight packet callbacks complete.
>>>>> However, with at most one thread running the callback per port/queue
>>>>> pair and no risk of the ABA problem, a boolean flag (true for in use,
>>>>> false for idle) suffices.
>>>>>
>>>>> Change member use to bool and replace the counter increment in the
>>>>> datapath with stores of true and false. Simplify bpf_eth_cbi_wait()
>>>>> to a direct pause loop waiting until the flag is false, removing the
>>>>> now unnecessary RTE_WAIT_UNTIL_MASKED macro and casts. Update the
>>>>> documentation and synchronization sequence diagram accordingly.
>>>>
>>>> As I explained in previous mail, it is not about even/odd.
>>>> It is about waiting while current 'quiscent' period will end.
>>>> By 'simplifying' that to use just boll values (0/1) you introduce
>>>> a live-lock in CP: it can be blocked for very long time waiting
>>>> while DP thread will keep processing packets.
>>>
>>> I do not think this explanation is correct. It was always waiting 
>>> only for the next value after the odd one, there are no cases where 
>>> anything else happens.
>>        /* 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)
--DP thread:
cbi->use = 2;
...
next rx burst:
cbi->use = 3;
                         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.



















More information about the dev mailing list