Add RTE_BPF_ETH_F_SKIP_MT_CHECK flag allowing callers to bypass the suitability check when installing BPF packet callbacks.
This allows overriding rejections in cases where the port or queue is configured with multi-thread capabilities (such as MT_LOCKFREE), but the application guarantees that only one dataplane thread accesses the queue at a time. Update the unit test to verify that callback installation succeeds when this flag is specified. Signed-off-by: Marat Khalili <[email protected]> --- app/test/test_bpf.c | 20 ++++++++++++++++++++ lib/bpf/bpf_pkt.c | 8 +++++--- lib/bpf/rte_bpf_ethdev.h | 5 ++++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/app/test/test_bpf.c b/app/test/test_bpf.c index 02523984b5..0ab8aa8759 100644 --- a/app/test/test_bpf.c +++ b/app/test/test_bpf.c @@ -4692,7 +4692,27 @@ test_bpf_elf_tx_mt_lockfree(load_elf_image_t load_elf_image) goto fail; } + /* Tx installation must succeed when check is skipped with flag */ + ret = rte_bpf_eth_tx_install(port, 0, bpf, RTE_BPF_ETH_F_SKIP_MT_CHECK); + if (ret != 0) { + printf("%s@%d: expected rte_bpf_eth_tx_install with SKIP_MT_CHECK to succeed, got %d\n", + __func__, __LINE__, ret); + ret = TEST_FAILED; + goto fail; + } + rte_bpf_eth_tx_unload(port, 0); + bpf = NULL; + /* Rx installation on the same port must still succeed */ + bpf = load_elf_image(app_test_bpf_filter_o, app_test_bpf_filter_o_len, "filter", + NULL, 0, &prog_arg); + if (bpf == NULL) { + printf("%s@%d: failed to load BPF filter image\n", + __func__, __LINE__); + ret = TEST_FAILED; + goto fail; + } + ret = rte_bpf_eth_rx_install(port, 0, bpf, 0); if (ret != 0) { printf("%s@%d: expected rte_bpf_eth_rx_install to succeed, got %d\n", diff --git a/lib/bpf/bpf_pkt.c b/lib/bpf/bpf_pkt.c index eab85f7417..7ee16cfa69 100644 --- a/lib/bpf/bpf_pkt.c +++ b/lib/bpf/bpf_pkt.c @@ -614,9 +614,11 @@ bpf_eth_elf_install(struct bpf_eth_cbh *cbh, uint16_t port, uint16_t queue, if (bpf->prm.nb_prog_arg != 1) return -EINVAL; - rc = bpf_eth_check_mt(cbh, port, queue); - if (rc != 0) - return rc; + if ((flags & RTE_BPF_ETH_F_SKIP_MT_CHECK) == 0) { + rc = bpf_eth_check_mt(cbh, port, queue); + if (rc != 0) + return rc; + } if (cbh->type == BPF_ETH_RX) frx = select_rx_callback(bpf->prm.prog_arg[0].type, flags); diff --git a/lib/bpf/rte_bpf_ethdev.h b/lib/bpf/rte_bpf_ethdev.h index cf3b4048f0..7a9f87e6cb 100644 --- a/lib/bpf/rte_bpf_ethdev.h +++ b/lib/bpf/rte_bpf_ethdev.h @@ -13,7 +13,8 @@ * - in the data plane, it expects only one thread per port/queue pair at a time. * Calling RX/TX burst functions concurrently on the same queue (e.g. when using * RTE_ETH_TX_OFFLOAD_MT_LOCKFREE, shared RX queues, or multi-threaded - * software PMDs) is not supported. + * software PMDs) is not supported and will be rejected at installation time + * unless overridden by RTE_BPF_ETH_F_SKIP_MT_CHECK. * - in the control plane, it is not MT safe, i.e. it is not allowed to do * load/unload for the same port/queue from different threads in parallel. * - though it allows load/unload at runtime @@ -37,6 +38,8 @@ extern "C" { enum { RTE_BPF_ETH_F_NONE = 0, RTE_BPF_ETH_F_JIT = 0x1, /**< use compiled into native ISA code */ + RTE_BPF_ETH_F_SKIP_MT_CHECK = 0x2, + /**< skip check for concurrent data plane thread usage */ }; /** -- 2.43.0

