Jijie Shao says:
====================
net: hns3: some cleanups for hns3 driver
Patch 1 sets msg->desc to NULL after kfree to avoid leaving a
dangling pointer in a struct that is reused across loop iterations.
Patch 2 adds the missing const qualifier to the reg parameter of
hclge_log_error(), which is never modified within the function.
Patch 3 uses the txqueue parameter passed by the ndo_tx_timeout
callback directly, instead of iterating all tx queues to find the
timed out one.
====================
Link: https://patch.msgid.link/20260807095435.2959246-1-shaojijie@huawei.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
The ndo_tx_timeout callback already provides the timed out txqueue
index. Use it directly instead of iterating all tx queues to find
the timed out one.
Use h->kinfo.num_tqps for the bounds check instead of
ndev->num_tx_queues, as the ring array is allocated with num_tqps
entries and num_tx_queues may be larger. This issue has not been
encountered in practice, so it is folded into this cleanup rather
than tracked as a separate bugfix.
Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260807095435.2959246-4-shaojijie@huawei.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Ivan Vecera says:
====================
dpll: use pin owner's dpll ref for pin-level set callbacks
Pin-level attributes (frequency, phase adjust, embedded sync, reference
sync) are properties of the pin itself. The get callbacks already use
only the pin owner's DPLL reference, but the set callbacks iterate over
all registered DPLL devices, resulting in redundant HW writes for
drivers that share a pin across multiple DPLLs.
This series simplifies the set side to match the get side: call the set
callback only through the owner's reference.
Patch 1 prepares the zl3073x driver whose ref_sync_set callback had
per-channel behavior (setting priority on a single DPLL channel). It now
iterates all channels internally so it remains correct when invoked only
once.
Patch 2 drops the xa_for_each loops from dpll_pin_freq_set(),
dpll_pin_esync_set(), dpll_pin_ref_sync_state_set() and
dpll_pin_phase_adj_set(), along with the rollback logic and the per-ref
-EOPNOTSUPP validation scan. The dpll.rst documentation is updated to
reflect the new behavior.
====================
Link: https://patch.msgid.link/20260807095926.386923-1-ivecera@redhat.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Pin-level attributes (frequency, phase adjust, embedded sync, reference
sync) are properties of the pin itself, not of a particular DPLL device.
The get callbacks already use only the pin owner's DPLL reference
(via dpll_pin_own_dpll_ref_first()), but the set callbacks iterate over
all registered DPLL references and invoke the set operation on each one.
This is redundant because a pin is a single physical entity - setting
its frequency or phase adjust once through the owner's ops is sufficient.
Calling set on every registered DPLL just results in duplicate HW writes
for drivers that share a pin across multiple DPLL devices (e.g. ice
registers each input pin with both the EEC and PPS DPLL, zl3073x
registers input pins with every DPLL channel).
Simplify dpll_pin_freq_set(), dpll_pin_esync_set(),
dpll_pin_ref_sync_state_set() and dpll_pin_phase_adj_set() to call the
set callback only through the owner's DPLL reference, matching the
existing get-side behavior. This removes the xa_for_each iteration
loops, the now-unnecessary rollback logic, and several local variables.
The -EOPNOTSUPP validation loop, which checked ops support across all
owner-matching references, is replaced with a direct check on the
single owner reference returned by dpll_pin_own_dpll_ref_first().
The documentation in dpll.rst is updated to reflect that pin-level
attributes are set through the pin owner's dpll reference only.
No existing driver is affected:
- ptp_ocp and mlx5 register each pin with a single DPLL.
- ice registers input pins with two DPLLs (EEC and PPS) using
identical ops and pin_priv; the set callbacks address the HW by
pin index, not by DPLL, so the second call was a no-op.
- zl3073x registers input pins with every DPLL channel; the set
callbacks address HW by pin/ref ID regardless of DPLL. The
ref_sync_set callback was the only one with per-channel behavior,
addressed by the preceding patch.
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Link: https://patch.msgid.link/20260807095926.386923-3-ivecera@redhat.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
zl3073x_dpll_input_pin_ref_sync_set() excludes the sync source from
automatic reference selection by setting its priority to NONE, but
currently only does this on the single DPLL channel whose pin_priv
was passed to the callback.
Since input pins are registered with every DPLL channel, the datasheet
recommends covering all channels to prevent the sync source from
remaining a selectable candidate on the other channels. This is
a preparation for the following patch which changes the DPLL core to
invoke pin-level set callbacks only through the pin owner's reference
instead of iterating over all registered DPLL devices.
Replace the single-channel priority write with a list_for_each_entry()
loop over all DPLL channels. Each channel's lock is acquired
individually for its read-modify-write sequence. The guard(mutex) is
replaced with explicit mutex_lock/mutex_unlock to allow releasing the
owner's lock before iterating, avoiding nested locking of the same
mutex class. A change notification is sent for the sync pin if any
channel's priority was actually modified.
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
Reviewed-by: Petr Oros <poros@redhat.com>
Link: https://patch.msgid.link/20260807095926.386923-2-ivecera@redhat.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
reuseport_bpf_numa case failed when testing on a platform with CXL
memory:
#./reuseport_bpf_numa
---- IPv4 UDP ----
send node 0, receive socket 0
./reuseport_bpf_numa: failed to pin to node: Invalid argument
The root cause is that the platform has 2 numa nodes: node 0 has
both cpu and memory, while node 1 is a CXL node which only has
memory, and caused numa_run_on_node() to fail.
Add sanity check to skip cpuless numa node for the numa binding test.
Signed-off-by: Feng Tang <feng.tang@linux.alibaba.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260807002436.43991-1-feng.tang@linux.alibaba.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
sctp_auth_calculate_hmac() can fail when building the association secret
under memory pressure, but its void return silently leaves the HMAC digest
zeroed. On the receive path, sctp_sf_authenticate() compares this zeroed
digest against the peer-supplied one using crypto_memneq(), potentially
accepting an all-zero HMAC from the peer if the allocation failed. On the
send path, sctp_packet_pack() transmits a packet with a zeroed HMAC that
the peer would reject.
Improve error handling by making sctp_auth_calculate_hmac() return int:
- sctp_sf_authenticate() returns SCTP_IERROR_NOMEM instead of accepting
a zero HMAC.
- sctp_packet_pack() drops the packet on failure instead of transmitting
a zeroed HMAC.
Update the declaration in auth.h accordingly.
Assisted-by: LLM
Signed-off-by: Qing Luo <luoqing@kylinos.cn>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20260807064314.500742-1-l1138897701@163.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Thaison Phan says:
====================
update NULL pointer handling in generated code
This series fixes potential NULL pointer dereferences in YNL-generated C
code during dump list freeing and memory allocation in parsing getters.
====================
Link: https://patch.msgid.link/20260807171500.7188-1-thaisonphan@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Generated YNL getter code does not check the return value of malloc() and
calloc() before passing the resulting pointer to memcpy(). This could lead
to a NULL pointer dereference on memory allocation failure.
Updated the C code generator to check for allocation failures and to return
an error code in getters.
Signed-off-by: Thaison Phan <thaisonphan@google.com>
Link: https://patch.msgid.link/20260807171500.7188-3-thaisonphan@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Static analysis detected code paths where freeing a dump list after early
errors when creating the corresponding dump list like in ynl_exec_dump()
can result in a null pointer dereference since the first node in the
ynl_dump_state would still be zero initialized. To prevent this potential
problem updated the ynl c generation script to check for a NULL pointer
before continuing to free the nodes in a dump list.
Signed-off-by: Thaison Phan <thaisonphan@google.com>
Link: https://patch.msgid.link/20260807171500.7188-2-thaisonphan@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
bond_reset() waits up to 2 seconds for IPv6 connectivity.
With default settings DAD itself may take almost 2 seconds,
causing flakes on debug builds. It used to flake once or
twice a week, recently it started failing once a day.
Probably some downstream changes to scheduler, or our machines
go busier.
A lot of selftests already use nodad, let's use nodad in bonding, too.
I don't see an obvious reason why DAD would be important to the test.
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260808162345.2442594-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
The ETF qdiscs drops traffic without a socket or txtime. Even with
parameter skip_sock_check regular traffic is affected by ETF.
This test ran fine when run manually in a pure software environment.
But with drv-net across two hosts tests fail as early as when calling
cfg.remote.deploy due to effectively losing connectivity.
Isolate the intended test traffic:
- mark that with SO_MARK 100
- install a regular permissive root prio qdisc for background traffic
- install the ETF qdisc as leaf
- install a filter that only directs SO_MARK 100 traffic to this leaf
Technically other high prio traffic will map onto this leaf based on
ToS band mapping too. But that is immaterial in practice.
Fixes: 5c6baef388 ("selftests: drv-net: convert so_txtime to drv-net")
Signed-off-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260808160129.890119-1-willemdebruijn.kernel@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
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>