DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: bugzilla@dpdk.org
To: dev@dpdk.org
Subject: [DPDK/ethdev Bug 2051] BPF inuse counter is not safe when using lockfree transmit
Date: Thu, 08 Oct 2026 22:14:58 +0000	[thread overview]
Message-ID: <bug-2051-3@https.bugs.dpdk.org/> (raw)

https://bugs.dpdk.org/show_bug.cgi?id=2051

            Bug ID: 2051
           Summary: BPF inuse counter is not safe when using lockfree
                    transmit
           Product: DPDK
           Version: 26.11
          Hardware: All
                OS: All
            Status: UNCONFIRMED
          Severity: normal
          Priority: Normal
         Component: ethdev
          Assignee: dev@dpdk.org
          Reporter: stephen@networkplumber.org
  Target Milestone: ---

The BPF ethdev callbacks (lib/bpf/bpf_pkt.c) guard cbi->bpf and cbi->jit
with a seqcount: bpf_eth_cbi_inuse() makes cbi->use odd,
bpf_eth_cbi_unuse() makes it even, and bpf_eth_cbi_wait() treats even as
"no thread is inside the callback". This is only valid with one thread
at a time in the callback for a given port/queue.

With RTE_ETH_TX_OFFLOAD_MT_LOCKFREE, multiple threads may call
rte_eth_tx_burst() on the same queue concurrently, so the tx callbacks
(bpf_tx_callback_vm/jit/mb_vm/mb_jit) run concurrently on the same cbi.

1. Parity. Two threads pass bpf_eth_cbi_inuse() and see cb != NULL; the
   count is even. rte_bpf_eth_tx_unload() clears cb, bpf_eth_cbi_wait()
   samples an even count and returns, and rte_bpf_destroy() frees the
   program and JIT code while both threads are executing it.
   Use after free.

2. Lost update. In the default build (enable_stdatomic=false) cbi->use++
   is a non-atomic read-modify-write. Concurrent increments can lose
   one, which inverts the parity permanently. An idle queue then reads
   odd, so bpf_eth_cbi_wait() spins until the next burst (forever if
   there is none), and afterwards even means in use, which leads back
   to case 1 with a single thread.

Rx is not affected; rx burst on a queue is never MT safe.

Nothing in rte_bpf_eth_tx_install() or rte_bpf_eth_tx_elf_load() checks
for the offload, and the restriction is not documented.

lib/pdump has the same pattern (pdump_cb_hold/pdump_cb_release/
pdump_cb_wait on use_count, used by pdump_tx) and the same problem.

Found by inspection while reviewing the conversion of rte_smp_mb() to
C11 fences. Not reproduced.

Possible fixes:
 - Fail tx install with -ENOTSUP when MT_LOCKFREE is enabled on the
   port or queue, and document it.
 - Replace the seqcount with a real reference count (atomic add/sub,
   wait for zero, keep the cb check). Costs two locked operations per
   burst.

-- 
You are receiving this mail because:
You are the assignee for the bug.

                 reply	other threads:[~2026-10-08 22:15 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-2051-3@https.bugs.dpdk.org/ \
    --to=bugzilla@dpdk.org \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox