net/mptcp/bpf.c | 1 + net/mptcp/protocol.h | 3 ++ net/mptcp/sched.c | 6 +++ .../testing/selftests/bpf/prog_tests/mptcp.c | 15 ++++++ tools/testing/selftests/bpf/progs/mptcp_bpf.h | 2 + .../selftests/bpf/progs/mptcp_bpf_avoid.c | 49 +++++++++++++++++++ 6 files changed, 76 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/mptcp_bpf_avoid.c
The core benches a subflow via the "stale" bit after net.mptcp.stale_loss_cnt retransmission intervals without progress. That bit is owned by the core and tightly coupled to the RTO: it is cleared as soon as a packet is acked on the subflow, in mptcp_subflow_active(). A packet scheduler therefore cannot repurpose it to bench a subflow for its own reasons (too high latency, too unstable) and keep it benched: the core would clear it on the next ack, unrelated to the scheduler's intent. Add a separate, scheduler-owned "avoid" flag on the subflow context, set and cleared only through mptcp_subflow_set_avoid(), exposed to BPF struct_ops schedulers as a kfunc (same registration and filter as mptcp_subflow_set_scheduled(), so only schedulers can call it). The flag is scheduler-local state: the scheduler sets it to remember a subflow should be skipped and consults it when picking a subflow to send on. It lives in the struct_group(reset) block, so it is cleared on subflow reset and a re-established path is re-evaluated. The core send and retransmit paths are left unchanged. This is the "manage a new bit" option from issue #349, kept independent of the RTO-driven stale bit as that issue requests. Regular probing of an avoided subflow (#348) and any core-side consumption of the flag are left for follow-up. Patch 1 adds the flag, the setter and the kfunc. Patch 2 adds a BPF struct_ops scheduler selftest that marks all but the first subflow avoided, reads the flag back, and schedules only a non-avoided subflow; the existing harness confirms the avoided path carries no data, exercising the kfunc round-trip from eBPF. Tested with the mptcp-upstream-virtme-docker CI (auto-normal and auto-btf): all selftests, packetdrill and BPF tests pass, including the new avoid subtest. Link: https://github.com/multipath-tcp/mptcp_net-next/issues/349 Kalpan Jani (2): mptcp: sched: add subflow avoid flag and kfunc selftests: mptcp: bpf: exercise the subflow avoid flag net/mptcp/bpf.c | 1 + net/mptcp/protocol.h | 3 ++ net/mptcp/sched.c | 6 +++ .../testing/selftests/bpf/prog_tests/mptcp.c | 15 ++++++ tools/testing/selftests/bpf/progs/mptcp_bpf.h | 2 + .../selftests/bpf/progs/mptcp_bpf_avoid.c | 49 +++++++++++++++++++ 6 files changed, 76 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/mptcp_bpf_avoid.c base-commit: 490b4823cb98b233af2b7562bddc90ecb5dfbf4e -- 2.43.0
On 7/15/26 12:11 PM, Kalpan Jani wrote: > The core benches a subflow via the "stale" bit after > net.mptcp.stale_loss_cnt retransmission intervals without progress. That > bit is owned by the core and tightly coupled to the RTO: it is cleared as > soon as a packet is acked on the subflow, in mptcp_subflow_active(). A > packet scheduler therefore cannot repurpose it to bench a subflow for its > own reasons (too high latency, too unstable) and keep it benched: the core > would clear it on the next ack, unrelated to the scheduler's intent. > > Add a separate, scheduler-owned "avoid" flag on the subflow context, set > and cleared only through mptcp_subflow_set_avoid(), exposed to BPF > struct_ops schedulers as a kfunc (same registration and filter as > mptcp_subflow_set_scheduled(), so only schedulers can call it). The flag is > scheduler-local state: the scheduler sets it to remember a subflow should > be skipped and consults it when picking a subflow to send on. It lives in > the struct_group(reset) block, so it is cleared on subflow reset and a > re-established path is re-evaluated. The core send and retransmit paths are > left unchanged. > > This is the "manage a new bit" option from issue #349, kept independent of > the RTO-driven stale bit as that issue requests. Regular probing of an > avoided subflow (#348) and any core-side consumption of the flag are left > for follow-up. > > Patch 1 adds the flag, the setter and the kfunc. Patch 2 adds a BPF > struct_ops scheduler selftest that marks all but the first subflow avoided, > reads the flag back, and schedules only a non-avoided subflow; the existing > harness confirms the avoided path carries no data, exercising the kfunc > round-trip from eBPF. > > Tested with the mptcp-upstream-virtme-docker CI (auto-normal and auto-btf): > all selftests, packetdrill and BPF tests pass, including the new avoid > subtest. > > Link: https://github.com/multipath-tcp/mptcp_net-next/issues/349 Please note that the above issue was filed before the introduction of the 'scheduled' flag. I don't see the `avoid` bool adding more capabilities on top of the other field, and without any usage from the core I think this change misses a relevant point from the linked issue. Finally the proposed patch creates a 4 bytes hole in the subflow struct, possibly a better location is available. More importantly you need to provide a meaningful working scenario demonstrating a relevant use-case not covered by the `scheduled` bit. /P
Hi Kalpan,
Thank you for your modifications, that's great!
Our CI did some validations and here is its report:
- KVM Validation: normal (except selftest_mptcp_join): Success! ✅
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Success! ✅
- KVM Validation: debug (only selftest_mptcp_join): Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/29409472750
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/11781b9663bb
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1128052
If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:
$ cd [kernel source code]
$ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
--pull always mptcp/mptcp-upstream-virtme-docker:latest \
auto-normal
For more details:
https://github.com/multipath-tcp/mptcp-upstream-virtme-docker
Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)
Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)
© 2016 - 2026 Red Hat, Inc.