From: Xin Xie <xiexinet@gmail.com>
To: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org,
linux-kernel@vger.kernel.org
Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, horms@kernel.org, andrew+netdev@lunn.ch,
shuah@kernel.org, kees@kernel.org, petr.wozniak@gmail.com,
qingfang.deng@linux.dev, fmaurer@redhat.com,
luka.gejak@linux.dev, bigeasy@linutronix.de,
xiaoliang.yang_1@nxp.com, skhawaja@google.com,
liuhangbin@gmail.com, stable@vger.kernel.org,
sdf.kernel@gmail.com, Xin Xie <xiexinet@gmail.com>
Subject: [PATCH net v6 0/4] net: hsr: fix GRO/GSO super-packet handling
Date: Sun, 9 Aug 2026 14:14:50 +0200 [thread overview]
Message-ID: <20260809121455.1745-1-xiexinet@gmail.com> (raw)
HSR/PRP requires per-wire-frame tags/RCTs and sequence numbers, and
duplicate discard is per frame. RX GRO and TX GSO can present
multiple frames as one skb and violate that assumption: a super-skb
is either rejected by a constrained lower device, or forwarded
without valid per-frame trailers and sequence numbers.
Patch 1 adds netif_disable_gro()/dev_disable_gro() and disables
GRO and GRO_HW on lower devices at HSR/PRP enslavement time,
mirroring the existing LRO treatment. Disabling is explicitly
best-effort: a later privileged override can re-enable GRO, and
devices with fixed-on GRO_HW (for example a virtio-net device
negotiating guest TSO without VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)
cannot be forced off, so enslavement succeeds whether or not the
feature could be cleared.
Patch 2 shrinks hsr->seqnr_lock from whole hsr_forward_skb() calls
to the sequence counter updates, so the segmentation work of
patch 3 never runs under the global sequence lock. The outer lock
also incidentally serialized the master/interlink tx statistics
updates in hsr_forward_skb(); those are now updated without the
outer lock, and consistent per-cpu/per-queue statistics for all HSR
paths (including hsr_deliver_master() and multicast) are handled in
a separate series.
Patch 3 unfolds GSO super-packets at the forward entry with the
top-level GSO dispatch (__skb_gso_segment()), so each wire frame
gets its own tag/RCT and sequence number. Admission is decided by a
content-based classifier, not by the ingress port: plain-Ethernet
aggregates are segmented on every ingress role (master, interlink,
and LAN slaves), while aggregates whose effective protocol is
ETH_P_HSR or ETH_P_PRP carry per-frame trailers that software
segmentation cannot reconstruct and are dropped. Aggregates with
unreadable net_iov (device-memory) fragments are also dropped: their
payload is not host-readable, and software segmentation would produce
segments with uninitialized payload that are silently dropped at
transmit or expose uninitialized data where netmem transmit is
enabled. The classifier unwraps accelerated VLAN and one in-band
VLAN level, and treats NETIF_F_HW_HSR_TAG_RM lowers as plain by
construction. The trailer-free premise of the plain-aggregate path is
proven for in-tree software GRO: its IPv4 and IPv6 length checks
reject frames with trailing bytes beyond the L3 length, so an
RCT-bearing PRP frame is not merged. Device-specific fixed-on GRO_HW
output is not claimed to be completely covered. Locally destined
segments are delivered to the host; the rest are forwarded per frame.
Patch 4 adds a kselftest covering the series, including a LAN-slave
plain-GSO regression: a plain SAN aggregate entering a PRP LAN slave
must be segmented, with local delivery and per-frame arrival proven
by independent counter oracles.
Patch 1 is a safe, partial, best-effort mitigation and is
independently stable-selectable; patch 3, named by subject in its
message, is the fallback for plain, trailer-free GSO aggregates.
Patch 3 depends on patch 2, and patches 2 and 3 are selected for
stable only where the sparse-bitmap duplicate discard is present,
which accepts out-of-order arrival. The stable tag names that
prerequisite, which exists only in 7.0 and newer.
Older branches need adapted backports.
Validation:
* the v6 kernel builds cleanly;
* LAN-slave plain-GSO regression on the v6 kernel: aggregates arrive
at the PRP master and are delivered per-frame (SAN TX avg ~38 KB
per frame; prp0 RX avg ~1476 B per frame);
* interlink super-packet test passes (DUT LAN legs avg ~1496 B per
frame with the SAN emitting ~38 KB super-packets);
* fixed-on GRO_HW: unchanged from v5 (patch 1 control flow
untouched); with a virtio guest negotiating TSO without
VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, HSR setup succeeds without the
v4-era "failed to disable GRO!" splat (v5 evidence reused);
* the bounded server-readiness/reap waits pass on the v6 kernel;
* hsr_ping, hsr_redbox, link_faults and prp_ping all pass;
* checkpatch: 0 errors; shellcheck unchanged from v5 (0 errors);
* the series applies cleanly with plain git am on current net.
Note on the net-next conflict: this series conflicts with our own PRP
RedBox support now merged in net-next
(https://lore.kernel.org/netdev/20260717201457.54-1-xiexinet@gmail.com/).
On current net it applies cleanly (re-verified by a full-series
git am). For net-next the conflict is confined to two sites:
1. net/hsr/hsr_device.c, send_prp_supervision_frame(): net-next
added the PRP RedBox Type-30 TLV and EOT construction where
patch 2/4 shrinks the seqnr_lock critical section. Resolution:
keep the lock release immediately after the sup_sequence_nr
update (as in this patch), build the whole TLV chain (LifeCheck
payload, Type-30 RedBox-MAC TLV, EOT) unlocked, and drop the
two stale unlocks from the padding-error and normal-exit paths.
2. tools/testing/selftests/net/hsr/Makefile: insert
hsr_gro_superpacket.sh at its sorted position.
The resolution was independently proven by composition on the
current net-next (4fa4977a0d90): the composed tree preserves the
Type-30 RedBox-MAC TLV and EOT construction with one balanced lock
region. This series' conflict-relevant hunks are unchanged from v5,
which applied and validated the same resolution on an earlier
net-next (2fbade662450): the composed tree builds cleanly and
hsr_prp_redbox.sh passes on the composed kernel.
---
Changes in v6:
A confirmed defect is fixed: a GSO aggregate carrying unreadable
net_iov (device-memory) fragments could reach the forward-entry
segmentation, where the software copy path cannot read such fragments
and would leave the segment payload uninitialized — silently dropped
at transmit on most devices, or exposing uninitialized data where
netmem transmit is enabled. v6 rejects such aggregates before
segmentation (skb_frags_readable() gate) and patch 3 describes this
accurately.
The selftest is hardened: the server reap now polls the wrapper's
status file instead of a recycled-PID candidate, server-PID
validation retries across the fork/exec window, and server readiness
polls the listening socket instead of a fixed sleep; all waits stay
bounded.
Further changes:
- patch 1: the comment now names fixed-on GRO_HW only (plain GRO is
always changeable).
- patch 3: the prerequisite is named by subject and commit; the
hw_features wording states the unconditional GSO_MASK removal (only
GSO_MASK member types become fixed-off;
generic-segmentation-offload stays changeable and is cleared at
runtime); the classifier comment describes its own policy.
- patch 4: the message describes the new test file, the header
documents the LAN-slave case, and the master-RX bound has its own
named constant.
- maintainer feedback adopted: patch 2 mentions commit aae9d6b616b5
("hsr: Implement more robust duplicate discard for HSR"), uses the
commit-annotated stable tag (verified equivalent to the former
7.0.x floor: the prerequisite exists only in 7.0.y/7.1.y), carries
the syzbot Reported-by/Closes pair and the two Fixes: tags, and
moves all statistics work out of the series (plain increments
restored; consistent per-cpu/per-queue statistics are a separate
follow-up series).
The remaining review findings were assessed and left unchanged: the
one-way best-effort GRO disable mirrors dev_disable_lro() and is
ethtool-recoverable; the kernel-doc already names the re-enable path;
out-of-order emission is tolerated by the sparse-bitmap duplicate
discard on both ends under the stable floor; the remaining statistics
races are accounting-precision issues covered by the follow-up
series; the software-GRO RCT claim holds (IPv4/IPv6 length checks
reject trailing bytes); the generic-segmentation-offload selftest
oracle was verified empirically on the identical tree; test cleanup
re-validates PID identity before signalling and has a netns-scoped
fallback; in-place skb mutations during forwarding are pre-existing
and handled by a separate series.
Previous postings (newest first):
v5: https://lore.kernel.org/netdev/20260807140751.1351-1-xiexinet@gmail.com/
v4: https://lore.kernel.org/netdev/20260803222211.877-1-xiexinet@gmail.com/
v3: https://lore.kernel.org/netdev/20260731090224.18-1-xiexinet@gmail.com/
v2: https://lore.kernel.org/netdev/20260724161253.79-1-xiexinet@gmail.com/
v1: https://lore.kernel.org/netdev/20260722171836.196-1-xiexinet@gmail.com/
Xin Xie (4):
net: hsr: fix packet drops caused by GRO superpackets
net: hsr: shrink seqnr_lock to sequence counter updates
net: hsr: unfold GSO super-packets at the forward entry
selftests: net: hsr: cover GSO super-packets on PRP slave ingress
include/linux/netdevice.h | 2 +
net/core/dev.c | 15 +
net/core/dev_api.c | 21 +
net/hsr/hsr_device.c | 17 +-
net/hsr/hsr_forward.c | 109 ++-
net/hsr/hsr_slave.c | 16 +-
tools/testing/selftests/net/hsr/Makefile | 1 +
.../selftests/net/hsr/hsr_gro_superpacket.sh | 678 ++++++++++++++++++
8 files changed, 835 insertions(+), 24 deletions(-)
create mode 100755 tools/testing/selftests/net/hsr/hsr_gro_superpacket.sh
--
2.43.0
next reply other threads:[~2026-08-09 12:14 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-09 12:14 Xin Xie [this message]
2026-08-09 12:14 ` [PATCH 1/4] net: hsr: fix packet drops caused by GRO superpackets Xin Xie
2026-08-09 12:14 ` [PATCH 2/4] net: hsr: shrink seqnr_lock to sequence counter updates Xin Xie
2026-08-10 2:23 ` Hangbin Liu
2026-08-09 12:14 ` [PATCH 3/4] net: hsr: unfold GSO super-packets at the forward entry Xin Xie
2026-08-09 12:14 ` [PATCH 4/4] selftests: net: hsr: cover GSO super-packets on PRP slave ingress Xin Xie
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=20260809121455.1745-1-xiexinet@gmail.com \
--to=xiexinet@gmail.com \
--cc=andrew+netdev@lunn.ch \
--cc=bigeasy@linutronix.de \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=fmaurer@redhat.com \
--cc=horms@kernel.org \
--cc=kees@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=liuhangbin@gmail.com \
--cc=luka.gejak@linux.dev \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=petr.wozniak@gmail.com \
--cc=qingfang.deng@linux.dev \
--cc=sdf.kernel@gmail.com \
--cc=shuah@kernel.org \
--cc=skhawaja@google.com \
--cc=stable@vger.kernel.org \
--cc=xiaoliang.yang_1@nxp.com \
/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