eeprom_wait_ready() returns a negative error when the LBCIF status
cannot be read or the device does not become ready for some other
reason.
eeprom_write() propagates this error before starting a write, but
currently returns 0 when the same readiness check fails after the
write begins.
This behavior was introduced when the EEPROM code was refactored to
use Linux error-return conventions (from 0 = failure to 0 = success).
Return the error so callers do not treat a failed EEPROM write as
successful and the function contract is maintained.
Cc: stable+noautosel@kernel.org # untested fix to unlikely driver error path
Signed-off-by: Avi Weiss <thnkslprpt@gmail.com>
Acked-by: Mark Einon <mark.einon@gmail.com>
Link: https://patch.msgid.link/20260808194347.813242-1-thnkslprpt@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
hwmon_sanitize_name() allocates sfp->hwmon_name before
hwmon_device_register_with_info() is called. If the registration
fails, sfp->hwmon_dev is left pointing to an error while
sfp->hwmon_name remains allocated.
Later, when the SFP module is removed, sfp_hwmon_remove() only frees
hwmon_name when hwmon_dev is valid. As a result, hwmon_name is leaked
if hwmon_device_register_with_info() fails.
Free hwmon_name independently of hwmon_dev. Continue to unregister the
hwmon device only when hwmon_dev was successfully registered.
Cc: stable+noautosel@kernel.org # untested fix to unlikely driver error path
Suggested-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Krishan Singh <krishanmohan298@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/20260809064504.70579-1-krishanmohan298@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Heiko Carstens says:
====================
drivers/s390/net: Enable CONTEXT_ANALYSIS
Enable CONTEXT_ANALYSYS for drivers/s390/net.
Static code checking for acquiring and releasing locks used to be done
with sparse. That was removed with [1] and replaced with a clang based
approach [2]. The new approach requires that each subsystem needs to be
explicitly enabled for checking.
Do that for drivers/s390/net. In order to avoid false positives due to
conditional locking, disable context analysis for specific functions of
the ctcm driver. All comments in ctcm indicate that the code should stay
as it is, and that such warnings should be ignored.
Disabling context analysis for specific functions keeps analysis enabled
for the rest of a file.
[1] 5b63d0ae94 ("compiler-context-analysis: Remove Sparse support")
[2] 3269701cb2 ("compiler-context-analysis: Add infrastructure for Context Analysis with Clang")
====================
Link: https://patch.msgid.link/20260805145032.1409325-1-hca@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Disable context analysis for various functions to get rid of context
analysis compile time warnings using clang caused by conditional
locking like e.g.:
drivers/s390/net/ctcm_fsms.c:1457:8:
warning: spinlock 'arg->cdev->ccwlock' is not held on every path through here
drivers/s390/net/ctcm_fsms.c:1459:4:
warning: releasing spinlock 'arg->cdev->ccwlock' that was not held
Use __context_unsafe() to provide a short comment why context analysis is
disabled for each function. Each of those functions already contains a
comment that the (previous) sparse context analysis warnings due to
conditional locking should be ignored.
Remove those comments everywhere and use the __context_unsafe() attribute
instead.
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Acked-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260805145032.1409325-2-hca@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Some devices refresh the statistics exposed via ethtool only
periodically, every stats-block-usecs (as reported by ethtool -c).
ethtool_std_stats and ethtool_rmon sample the counters immediately
after generating traffic, so on such devices they can read stale
values and fail with a delta short of the packets just sent.
Add a hw_stats_settle() helper which sleeps for 1.25x the configured
stats-block-usecs (defaulting to 20ms when the device reports no, or
a zero, period). Use it for ethtool std stats and RMON.
The 1.25x/20msec heuristic matches what the Python tests do.
Reviewed-by: Petr Machata <petrm@nvidia.com>
Link: https://patch.msgid.link/20260808163653.2460381-2-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
mausezahn defaults to sending packets back to back at the maximum rate,
which can cause packet loss, especially if receiver is running a debug
kernel. Space the generated packets out (-d 10usec), like ethtool_rmon
already does.
Reviewed-by: Petr Machata <petrm@nvidia.com>
Link: https://patch.msgid.link/20260808163653.2460381-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
The adaptive-rx and adaptive-tx checks use 'ethtool -c | grep -q' under
'set -o pipefail'. grep -q exits as soon as it finds a match, which can
happen before ethtool finishes writing its output. When that occurs,
ethtool receives SIGPIPE causing (uninformative):
# selftests: drivers/net/netdevsim: ethtool-coalesce.sh
# FAILED 1/22 checks
not ok 1 selftests: drivers/net/netdevsim: ethtool-coalesce.sh # exit=1
This happens on debug kernels in NIPA, ~4% of the time.
Link: https://patch.msgid.link/20260808163416.2456810-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
The USO features in set_offload() incorrectly uses feature_mask and
features argument.
The USO feature was written to the local features variable instead of
feature_mask. All other offload bits (TSO, TSO_ECN) are stored in
feature_mask which becomes tap->tap_features and is used by
tap_handle_frame() for GSO segmentation. Without NETIF_F_GSO_UDP_L4
in tap->tap_features, making USO on tap effectively non-functional.
Keeping the USO handling inside the TUN_F_CSUM block avoids enabling
GRO/LRO when userspace requests USO without CSUM.
This has not worked since the beginning, so
commit 399e082764 ("driver/net/tun: Added features for USO.")
Signed-off-by: Rongguang Wei <weirongguang@kylinos.cn>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260807070914.112698-1-clementwei90@163.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
"xlnx,rxmem" device-tree property is used to learn the size of the Rx/Tx
packet buffer built into the ethernet IP, but return value of
of_property_read_u32() is ignored. When the property is absent lp->rxmem is
left at 0, which silently limits the interface to the default MTU and
disables jumbo frames with no indication of the misconfiguration.
"xlnx,rxmem" has been documented as a required property since the binding
was introduced. Check the return value of of_property_read_u32() and fail
probe when the property is missing, so a misconfigured device tree is
reported rather than silently degrading functionality.
Signed-off-by: Suraj Gupta <suraj.gupta2@amd.com>
Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
Link: https://patch.msgid.link/20260806170253.1199749-1-suraj.gupta2@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
When a lower device is unregistered, amt_device_event() tries
to unregister its upper AMT device, but it has two problems.
1. amt_lookup_upper_dev() looks up an upper device in the
lower device's netns only
2. amt_device_event() unregisters a single upper device only
If AMT device is created on a lower device in another netns,
removing the lower device triggers the splat below and gets
stuck until all upper devices are removed. [0]
The cross-netns setup seems unintentional considering 1. and
the following points:
* amt_link_setup() sets dev->netns_immutable to true
* skb_scrub_packet() is not called in the fast path
* iproute2 binary fails to find cross-netns lower device via
link-netns:
# ip -n ns1 link add amt0 link-netns ns2 type amt dev veth1
Cannot find device "veth1"
Instead of supporting it properly and preparing for per-netns
netdev unreg, let's forbid cross-netns setup.
Note that the problem 2. needs a separate fix.
[0]:
WARNING: net/core/dev.c:12518 at unregister_netdevice_many_notify+0x1cce/0x2250, CPU#48: ip/2031
Modules linked in:
CPU: 48 UID: 0 PID: 2031 Comm: ip Not tainted 7.2.0-rc5+ #27 PREEMPT(full)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
RIP: 0010:unregister_netdevice_many_notify (net/core/dev.c:12518)
Code: 89 ef e8 d5 52 ae fe e9 d0 f4 ff ff 48 8d 3d f9 3b 9c 02 48 c7 c6 c0 0b 63 84 ba ab 1f 00 00 67 48 0f b9 3a e9 65 ff ff ff 90 <0f> 0b 90 eb 81 48 8d 3d f6 3b 9c 02 48 c7 c6 c0 0b 63 84 ba e2 1f
RSP: 0018:ffffc90004abf160 EFLAGS: 00010212
RAX: ffff888104d38260 RBX: ffff88800b0911b8 RCX: dffffc0000000000
RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffffffff85b9f880
RBP: ffffc90004abf2d0 R08: ffffffff85b9f887 R09: 1ffffffff0b73f10
R10: dffffc0000000000 R11: fffffbfff0b73f11 R12: ffff88800b091d08
R13: ffff88800b091178 R14: dffffc0000000000 R15: ffff88800b091000
FS: 00007f555b86c600(0000) GS:ffff8881942a0000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000562107d489c0 CR3: 0000000109a40002 CR4: 0000000000372ef0
Call Trace:
<TASK>
rtnl_dellink (net/core/rtnetlink.c:3632 net/core/rtnetlink.c:3674)
rtnetlink_rcv_msg (net/core/rtnetlink.c:7112)
netlink_rcv_skb (net/netlink/af_netlink.c:2556)
netlink_unicast (net/netlink/af_netlink.c:1319)
netlink_sendmsg (net/netlink/af_netlink.c:1900)
____sys_sendmsg (net/socket.c:775)
__sys_sendmsg (net/socket.c:2738)
do_syscall_64 (arch/x86/entry/syscall_64.c:63)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
...
unregister_netdevice: waiting for veth0 to become free. Usage count = 7
ref_tracker: netdev@ffff88800d7496d8 has 3/3 users at
__netdev_adjacent_dev_insert (./include/linux/netdevice.h:4525 ./include/linux/netdevice.h:4554 net/core/dev.c:8791)
__netdev_upper_dev_link (net/core/dev.c:8879 net/core/dev.c:8963)
netdev_upper_dev_link (net/core/dev.c:9009)
amt_newlink (drivers/net/amt.c:3321)
Fixes: b9022b53ad ("amt: add control plane of amt interface")
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Taehee Yoo <ap420073@gmail.com>
Link: https://patch.msgid.link/20260807020326.2519445-1-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Add a new PHY driver for the DAPU Telecom DAP8211R(I) Gigabit
Ethernet PHY, which is commonly used in enterprise and industrial
networking applications.
The driver implements extended register access via indirect addressing
through corresponding registers, and provides comprehensive device tree
support for RGMII delay configuration. The rx-internal-delay-ps and
tx-internal-delay-ps properties allow precise tuning of clock delays in
150 ps steps from 0 to 2250 ps.
Signed-off-by: Artem Shimko <a.shimko.dev@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/20260805085540.452260-4-a.shimko.dev@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
The commit message for af8c8a450b ("selftests: net: Add FIN_ACK
processing order related latency spike test") states: "if the latency
is larger than 1 second (spike), print a message". However the code
uses a threshold of 100000 us (100 ms), not 1000000 us (1 s).
The lower threshold causes false positives on slower hardware where
normal connection latency occasionally exceeds 100 ms but never
approaches the 1 s spike that indicates the actual FIN/ACK race bug.
Fix the threshold to match the documented intent.
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Brian Grech <bgrech@redhat.com>
Link: https://patch.msgid.link/20260806151645.4172900-1-bgrech@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Add a new devmem test case for binding the dmabuf with rx-page-size=16K.
The test sweeps RX payload sizes straddling the niov boundary to cover
the sub-niov, exact-niov, and multi-niov RX paths.
Silence pylint invalid-name (`with open() as f`) and too-many-arguments
(ncdevmem_rx grew to 6 args) at file scope.
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
Link: https://patch.msgid.link/20260805-tcpdm-large-niovs-v8-3-3e0225e2808c@meta.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Ivan has been continuously active in DPLL development and discussion
since April 2025. His contributions cover the DPLL core and API,
netlink, bindings, ICE/SyncE integration, and the ZL3073x driver.
He also regularly reviews and tests DPLL patches from other contributors
and already maintains the Microchip ZL3073x driver. Add him as a reviewer
to reflect his ongoing involvement across the subsystem.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Acked-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Acked-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Link: https://patch.msgid.link/20260806094432.163833-1-jiri@resnulli.us
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Jiawen Wu says:
====================
net: wangxun: timeout and error
It is about adding the Tx timeout process and pci_error_handlers.
When a PCIe error occurs, the txgbe device is able to recover on platform
that support AER interrupt. And for Tx timeout, the txgbe driver can
recover the device by reset process.
For ngbe devices, due to the absence of the current function, it cannot
br fully recovered once there is a PCIe error or Tx timeout. Its
function will be completed in the future.
====================
Link: https://patch.msgid.link/20260803064334.21876-1-jiawenwu@trustnetic.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Support AER driver to handle the PCIe errors. Sometimes netdev watchdog
Tx timeout happens before the AER error report when a PCIe error occurs,
CPU blocking would be caused by MMIO during the reset process. To
prevent it, check PCIe error status in .ndo_tx_timeout. The current
function of ngbe is not yet fully developed, it will be completed in the
future.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Link: https://patch.msgid.link/20260803064334.21876-6-jiawenwu@trustnetic.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Function wx_soft_quiesce() provide a lightweight shutdown path during
PCIe error recovery. It avoids MMIO-dependent operations in PCIe error
status.
Waiting for the service task to complete may unnecessarily delay PCIe
error recovery, especially if the work item is already blocked by the
hardware failure that triggered AER. So the service task is not
explicitly cancelled in quiesce path. As a measure to block the service
task, the checking of WX_STATE_DOWN and WX_STATE_RESETTING is added at
the entry of relevant work item.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Link: https://patch.msgid.link/20260803064334.21876-5-jiawenwu@trustnetic.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Implement .ndo_tx_timeout to handle Tx side timeout event. When a Tx
timeout event occur, it will trigger driver into reset process. And
allocate a separate work queue for reset process.
The WX_HANG_CHECK_ARMED bit is set to indicate a potential hang. It will
be cleared if a pause frame is received to avoid false hang detection
caused by pause frames.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Link: https://patch.msgid.link/20260803064334.21876-3-jiawenwu@trustnetic.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Simon Schippers says:
====================
tun/tap & vhost-net: apply qdisc backpressure on full ptr_ring to reduce TX drops
This patch series deals with tun/tap & vhost-net which drop incoming
SKBs whenever their internal ptr_ring buffer is full. Instead, with this
patch series, the associated netdev queue is stopped, but only when the
new IFF_BACKPRESSURE flag is set and a qdisc is attached. Without the
flag, or if no qdisc is present, the existing behavior is preserved. The
XDP transmit path is not affected. This patch series touches tun/tap and
vhost-net, as they share common logic and must be updated together.
Modifying only one of them would break the other.
By applying proper backpressure, this change allows the connected qdisc to
operate correctly, as reported in [1], and significantly improves
performance in real-world scenarios, as demonstrated in our paper [2]. For
example, we observed a 36% TCP throughput improvement for an OpenVPN
connection between Germany and the USA.
The previous version of this work was applied and then reverted in 7.2,
because the backpressure was unconditional: it caused a significant
throughput drop in an IPv6 multicast testcase with multiple iperf3 TCP
threads sending on Brett Sheffield's librecast testbed [3]. This version
therefore makes the behavior opt-in via IFF_BACKPRESSURE from the very
first patch, so that a tun/tap device which does not set the flag behaves
exactly as before.
The series is ordered so that no patch changes how packets are handled
unless the flag is set:
- Patch 1 adds the flag only. It has no effect yet: TUNSETIFF silently
masks it off, as it does for any flag outside TUN_FEATURES, until
patch 5 adds it there.
- Patches 2 and 3 add the consumer side, which wakes a stopped netdev
queue. __tun_wake_queue() returns early unless IFF_BACKPRESSURE is set,
and no queue is stopped at this point anyway.
- Patch 4 is a pure ptr_ring refactor required by patch 5.
- Patch 5 adds the queue stopping, gated on IFF_BACKPRESSURE, together
with the wake needed when the flag is cleared again, and only there is
the flag added to TUN_FEATURES.
That way no intermediate commit changes the behavior of an existing
tun/tap user beyond the added checks, and bisecting inside the series can
not hit the regression that led to the revert.
[1] https://unix.stackexchange.com/questions/762935/traffic-shaping-ineffective-on-tun-device
[2] https://cni.etit.tu-dortmund.de/storages/cni-etit/r/Research/Publications/2025/Gebauer_2025_VTCFall/Gebauer_VTCFall2025_AuthorsVersion.pdf
[3] https://lore.kernel.org/netdev/akVnoOYQOrt8k-Gu@karahi.librecast.net/
====================
Link: https://patch.msgid.link/20260803183641.96882-1-simon.schippers@tu-dortmund.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit prevents tail-drop when IFF_BACKPRESSURE is set, a qdisc is
present and the ptr_ring becomes full. Once the ring reaches capacity
after a produce attempt, the netdev queue is stopped instead of dropping
subsequent packets. Without the flag, or if no qdisc is present, the
previous tail-drop behavior is preserved.
IFF_BACKPRESSURE is added to TUN_FEATURES here and not in the patch that
defines it, so that TUNSETIFF honours the flag only once the
implementation behind it is complete.
The unconditional version of this behavior was reverted because it caused
a significant throughput drop in an IPv6 multicast testcase on Brett
Sheffield's librecast testbed [1]: with 8 iperf3 TCP threads sending, the
throughput dropped from 13.5 Gbit/s to 9.13 Gbit/s. This is why the queue
stopping is now gated on IFF_BACKPRESSURE.
If producing an entry fails anyway due to a race, tun_net_xmit() drops
the packet. Such rare races are expected because LLTX is enabled and the
transmit path operates without the usual locking.
The queue state is only touched while the device is running. The stop
itself would be harmless during teardown, as tun_net_close() sets the
same bit, but the re-check below it wakes the queue again and must not
clear that stop.
A later TUNSETIFF can clear the flag again while the device has at most
one queue. Past that point tun_set_iff() returns before it writes
tun->flags, which is how it already treats every other TUN_FEATURES bit.
For the case where the flag does change, tun_set_iff() calls
tun_force_wake_queue() for the attached tfiles, so that no queue stays
stopped without a consumer that would wake it.
The __tun_wake_queue() function of the consumer races with the producer
for waking/stopping the netdev queue, which could result in a stalled
queue. Therefore, an smp_mb__after_atomic() is introduced that pairs
with the smp_mb() of the consumer. It follows the principle of store
buffering described in tools/memory-model/Documentation/recipes.txt:
- The producer in tun_net_xmit() first sets __QUEUE_STATE_DRV_XOFF,
followed by an smp_mb__after_atomic() (= smp_mb()), and then reads the
ring with __ptr_ring_check_produce().
- The consumer in __tun_wake_queue() first writes zero to the ring in
__ptr_ring_consume(), followed by an smp_mb(), and then reads the queue
status with netif_tx_queue_stopped().
=> Following the aforementioned principle, it is impossible for the
producer to see a full ring (and therefore not wake the queue on the
re-check) while the consumer simultaneously fails to see a stopped
queue (and therefore also does not wake it).
tun_net_xmit() holds only the producer_lock and can not reset cons_cnt,
which the consumer_lock protects, so the wake on the re-check leaves
stale credit behind. That is accepted as best-effort, the re-check rarely
succeeds and the next drain corrects the count.
The documentation in tuntap.rst is updated accordingly.
Benchmarks:
My own benchmarks show a slight regression in raw transmission performance
when using two sending threads. Packet loss also occurs only in the
two-thread sending case; no packet loss was observed with a single
sending thread.
Test setup:
AMD Ryzen 5 5600X at 4.3 GHz, 3200 MHz RAM, isolated QEMU threads;
Average over 50 runs @ 100,000,000 packets. SRSO and spectre v2
mitigations disabled.
Note for tap+vhost-net:
XDP drop program active in VM -> ~2.5x faster; slower for tap due to
more syscalls (high utilization of entry_SYSRETQ_unsafe_stack in perf)
+--------------------------+--------------+----------------+----------+
| 1 thread | Stock | Patched with | diff |
| sending | | fq_codel qdisc | |
+------------+-------------+--------------+----------------+----------+
| TAP | Received | 1.132 Mpps | 1.123 Mpps | -0.8% |
| +-------------+--------------+----------------+----------+
| | Lost/s | 3.765 Mpps | 0 pps | |
+------------+-------------+--------------+----------------+----------+
| TAP | Received | 3.857 Mpps | 3.901 Mpps | +1.1% |
| +-------------+--------------+----------------+----------+
| +vhost-net | Lost/s | 0.802 Mpps | 0 pps | |
+------------+-------------+--------------+----------------+----------+
+--------------------------+--------------+----------------+----------+
| 2 threads | Stock | Patched with | diff |
| sending | | fq_codel qdisc | |
+------------+-------------+--------------+----------------+----------+
| TAP | Received | 1.115 Mpps | 1.081 Mpps | -3.0% |
| +-------------+--------------+----------------+----------+
| | Lost/s | 8.490 Mpps | 391 pps | |
+------------+-------------+--------------+----------------+----------+
| TAP | Received | 3.664 Mpps | 3.555 Mpps | -3.0% |
| +-------------+--------------+----------------+----------+
| +vhost-net | Lost/s | 5.330 Mpps | 938 pps | |
+------------+-------------+--------------+----------------+----------+
[1] https://lore.kernel.org/netdev/akVnoOYQOrt8k-Gu@karahi.librecast.net/
Co-developed-by: Tim Gebauer <tim.gebauer@tu-dortmund.de>
Signed-off-by: Tim Gebauer <tim.gebauer@tu-dortmund.de>
Signed-off-by: Simon Schippers <simon.schippers@tu-dortmund.de>
Link: https://lore.kernel.org/netdev/akVnoOYQOrt8k-Gu@karahi.librecast.net/
Link: https://patch.msgid.link/20260803183641.96882-6-simon.schippers@tu-dortmund.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This patch moves the check for available free space for a new entry into
a separate function. Existing callers that only check for a non-zero
return value are unaffected. __ptr_ring_produce() now returns -EINVAL
for a zero-size ring and -ENOSPC when full, whereas before both cases
returned -ENOSPC. The new helper allows callers to determine in advance
whether a single subsequent __ptr_ring_produce() call will succeed. This
information can, for example, be used to temporarily stop producing until
__ptr_ring_check_produce() indicates that space is available again.
The return values are documented above the helper, as a caller that waits
for space must distinguish the transient -ENOSPC from the permanent
-EINVAL.
Co-developed-by: Tim Gebauer <tim.gebauer@tu-dortmund.de>
Signed-off-by: Tim Gebauer <tim.gebauer@tu-dortmund.de>
Signed-off-by: Simon Schippers <simon.schippers@tu-dortmund.de>
Link: https://patch.msgid.link/20260803183641.96882-5-simon.schippers@tu-dortmund.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Add tun_wake_queue() to tun.c and export it for use by vhost-net. The
function validates that the file belongs to a device implemented by
drivers/net/tun.c, in IFF_TUN as well as in IFF_TAP mode, and that the
tfile exists, dereferences the tun_struct under RCU, and delegates to
__tun_wake_queue().
vhost_net_buf_produce() now calls tun_wake_queue() after a successful
batched consume of the ring to allow the netdev subqueue to be woken up.
The point is to allow the queue to be stopped when it gets full, which is
required for traffic shaping, implemented by the following
"stop tail-drop when IFF_BACKPRESSURE is set".
As __tun_wake_queue() returns early unless IFF_BACKPRESSURE is set, a
tun/tap device that does not opt in only pays for the added check.
macvtap and ipvtap rings, which get_tap_ptr_ring() accepts too, are
unaffected: their producer is the tap_handle_frame() rx_handler and not
ndo_start_xmit, so stopping a netdev TX queue would not hold it back.
drivers/net/tap.c has no netdev_ops of its own either. No
tap_wake_queue() is needed.
cons_cnt and the wake decision are best-effort and are not reverted by
ptr_ring_unconsume(), so vhost_net_buf_unproduce() can leave the subqueue
woken over a full ring. The producer re-stops it on the next packet, and
that path only runs from vhost_net_stop_vq() and vhost_net_set_backend(),
when the consumer is going away, so a stopped queue is the correct end
state rather than a stall.
Co-developed-by: Tim Gebauer <tim.gebauer@tu-dortmund.de>
Signed-off-by: Tim Gebauer <tim.gebauer@tu-dortmund.de>
Signed-off-by: Simon Schippers <simon.schippers@tu-dortmund.de>
Link: https://patch.msgid.link/20260803183641.96882-4-simon.schippers@tu-dortmund.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Introduce tun_ring_consume() that wraps ptr_ring_consume() and calls
__tun_wake_queue(). The latter wakes the stopped netdev subqueue once
half of the ring capacity has been consumed, tracked via the new
cons_cnt field in tun_file. As a safety net, the queue is also woken on
the last consumed entry if it leaves the ring empty. The point is to
allow the queue to be stopped when it gets full, which is required for
traffic shaping, implemented by the following "stop tail-drop when
IFF_BACKPRESSURE is set".
__tun_wake_queue() returns early unless IFF_BACKPRESSURE is set, so for a
tun/tap device that does not opt in only the added check on the consume
path remains.
Every site that clears __QUEUE_STATE_DRV_XOFF now checks netif_running()
under a ring lock that tun_net_close() takes, so that none of them undoes
its stop. The core sets it before it calls ndo_open() and clears it
before it calls ndo_stop(), so it is false for exactly as long as the
device is down. IFF_UP would not do, it is only cleared after ndo_stop()
returns.
Some implementation details:
- tun_ring_recv() replaces ptr_ring_consume() with tun_ring_consume()
to properly wake the queue.
- __tun_wake_queue() returns early for a device that is not running, so a
stop from tun_net_close() is not mistaken for backpressure, and it only
wakes if the tfile still owns its slot in tun->tfiles[]. A detached
tfile keeps its queue_index, which __tun_detach() may already have
handed to the tfile that took over the slot.
- lockdep_assert_held() enforces the documented consumer_lock
precondition of __tun_wake_queue().
- __tun_detach() locks the tx_ring.consumer_lock to avoid races with
the consumer on the queue_index, and that of tfile across the hand-over
of the slot, which makes the ownership check above exact.
- The ptr_ring_consume() call in tun_queue_purge() is not replaced with
tun_ring_consume(). Instead __tun_detach() wakes the netdev queue for
the ntfile taking it over, to avoid a possible stall. The queue is only
woken if the ring of the ntfile is empty, as otherwise the consumer
wakes it after consuming the remaining entries. This does not matter
for tun_detach_all(), as it is called during device teardown and no
tfile takes over any queue.
- That wake sits after synchronize_net() and tun_queue_purge(), so it can
not be undone by a concurrent tun_net_xmit() or __tun_wake_queue().
- Ensure detached queues are woken on re-attach by calling the new
tun_force_wake_queue() helper from tun_attach(), and reuse it across
the existing wake paths. Unlike __tun_wake_queue() it ignores
IFF_BACKPRESSURE, so a queue can not stay stopped after the flag is
cleared. It does honour netif_running(), but it always clears cons_cnt,
so no old count is left over when the queue is stopped again.
- tun_net_close() takes and releases both ring locks of every tfile
before netif_tx_stop_all_queues(), so that its stop is the last write
to __QUEUE_STATE_DRV_XOFF.
- The aforementioned upcoming patch explains the pairing of the smp_mb()
of __tun_wake_queue().
Co-developed-by: Tim Gebauer <tim.gebauer@tu-dortmund.de>
Signed-off-by: Tim Gebauer <tim.gebauer@tu-dortmund.de>
Signed-off-by: Simon Schippers <simon.schippers@tu-dortmund.de>
Link: https://patch.msgid.link/20260803183641.96882-3-simon.schippers@tu-dortmund.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Add the IFF_BACKPRESSURE flag to the UAPI header and to its tools/ copy.
The flag has no effect yet, it is the opt-in switch for the qdisc
backpressure logic added by the following patches.
It is added to TUN_FEATURES only in the last patch of the series, once the
implementation is complete. Until then TUNSETIFF silently masks it off, as
it does for any flag outside TUN_FEATURES.
Keeping the flag and its users in separate patches would either leave a
window where backpressure is unconditional, or make the opt-in a later
add-on. Adding the flag first lets every following patch be a no-op
unless it is set.
Signed-off-by: Simon Schippers <simon.schippers@tu-dortmund.de>
Link: https://patch.msgid.link/20260803183641.96882-2-simon.schippers@tu-dortmund.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Mohsin Bashir says:
====================
selftests: net: shaper: Expand shaper API coverage
Add more net shaper selftest coverage for group operations and nested
node management.
The series first prepares shared cleanup and capability helpers, and
separates the basic netdev grouping coverage from the rate-limited
variant. It then adds tests for updating node shaper rates through both
.set and .group, discovering the supported nesting depth, deleting child
nodes and reparenting their leaves, moving queues between nodes, and
rejecting node reparenting.
Further patches broaden API coverage: exercising the full set of scalar
shaper attributes, rejecting invalid .set requests while leaving the
existing configuration intact, grouping leaves drawn from different
parents (which requires an explicit parent), and recursively cleaning up
nodes left empty.
The new tests use the capability helper to skip unsupported devices
instead of depending on earlier test ordering, size their queue
requirements from the number of TX queues exposed in sysfs, and register
cleanup for created shapers as soon as the operation succeeds.
TAP version 13
1..22
ok 1 shaper.get_shapers
ok 2 shaper.get_caps
ok 3 shaper.set_qshapers
ok 4 shaper.del_qshapers
ok 5 shaper.set_nshapers
ok 6 shaper.del_nshapers
ok 7 shaper.set_all_supported_attrs
ok 8 shaper.invalid_set_preserves_state
ok 9 shaper.mixed_parent_group_requires_parent
ok 10 shaper.recursive_empty_node_cleanup
ok 11 shaper.basic_groups
ok 12 shaper.basic_groups_with_rate
ok 13 shaper.qgroups
ok 14 shaper.set_node_shaper
ok 15 shaper.group_update_rate
ok 16 shaper.delegation
ok 17 shaper.nested_depth_limit
ok 18 shaper.delete_child_reparent
ok 19 shaper.move_queue_between_nodes
ok 20 shaper.reject_reparenting
ok 21 shaper.dup_leaves
ok 22 shaper.queue_update
====================
Link: https://patch.msgid.link/20260805030936.1092907-1-mohsin.bashr@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Exercise queue-scope scalar shaper attributes reported by the device,
including rate limits, burst, priority and weight. Build the set request
from advertised capabilities so devices are tested for the attributes they
claim rather than skipped for missing unrelated fields.
Signed-off-by: Mohsin Bashir <hmohsin@meta.com>
Link: https://patch.msgid.link/20260805030936.1092907-12-mohsin.bashr@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Add reject_reparenting to verify that the group operation rejects attempts
to change an existing node's parent. The test creates two node shapers
under netdev and verifies that re-grouping the first node under the second
fails with EOPNOTSUPP. It also verifies that updating the node with the
same parent succeeds, and that updating the node without specifying a
parent keeps the queue leaves under the original node while updating their
weights.
Signed-off-by: Mohsin Bashir <hmohsin@meta.com>
Link: https://patch.msgid.link/20260805030936.1092907-11-mohsin.bashr@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Add move_queue_between_nodes to verify that a queue can be moved
from one node to another via re-grouping. Creates N1 with Q1,Q2
and N2 with Q3, then re-groups N2 with Q1,Q3 to steal Q1 from
N1. Verifies Q1 moved to N2 and Q2 remains under N1.
Signed-off-by: Mohsin Bashir <hmohsin@meta.com>
Link: https://patch.msgid.link/20260805030936.1092907-10-mohsin.bashr@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Add nested_depth_limit to incrementally create deeper nesting
levels until the driver rejects. Reports the maximum supported
nesting depth on both pass and fail. A device advertising nesting
support must support at least depth 2, otherwise nesting is
meaningless.
Signed-off-by: Mohsin Bashir <hmohsin@meta.com>
Link: https://patch.msgid.link/20260805030936.1092907-8-mohsin.bashr@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>