From nobody Fri Jul 24 22:51:56 2026 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EC90A439F71 for ; Wed, 22 Jul 2026 17:18:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784740723; cv=none; b=MWZ4WWOxv2GGPv4G5hI/AURe4N6bIzWocVvHZ7dsSGZ6eM06atwYNzeMiavQjZ5sPZJctzRhB7JC0hxpBYyvAigg3gEu0H/YQ62XXsbNbXJX+JA5aLzIBGB2s4nWSoC8x547atuDY74QoGh9v9QT/I84Vl3lrTkClD+JmlDARds= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784740723; c=relaxed/simple; bh=T6VI/MjUMTWjR0YmJzrLiiKf7zo+1Zk/2lAOGfSsHHM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KG/U8Tx/nLEvzBo22N8G7GkuOXYDo/0j1r1p00zJI/mrcwP/CvDb5qjJY5A5cpksoAg+0OAMNHQJ6UqmyOCaoY6Cz0QGO5NNFq7kzWVysEBxBF1ba3SCORXqiEPzHWyBZl8iJ/ynUZcWYS/gZtwfKzVqnGFEdtmCAGtC8NCzArc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=h0AOnUaz; arc=none smtp.client-ip=209.85.128.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="h0AOnUaz" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-4956d1d9fb2so97065e9.0 for ; Wed, 22 Jul 2026 10:18:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784740720; x=1785345520; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=cRQ5TWPONEvJdayuRFKl7W3Z0rghnTrzVVZ4y0zRgw0=; b=h0AOnUazKFb+8b3m+V7160UIw0rFzoQ7s7guhMaVYmmF3xWsM2ESTfOoRuURjuCkBf 35Y54tH3KlFoC/ZQQGQux2G24clI7v+nLALObSv7h2d1F8VZetR3rA/6fnYY04gcPeeR V5sB4azWuLHrQ0rD1s5Wox3WhOnOG0ajne3eM9AecDQV5zQBxhPcHA1HOoh/BVhb8eWW WXrWJJ+bAbndxfYKZXcHQmAE2I4vLwgblmKe2WPBKiS7ALSxN3Q9F5N/nOAerEoq2oEx qOGflCWN0ej61uXGPBqAouOt2BLj9jXAUeYrEAxz814FYYFd37apaft9b4Xn66ThVQb+ uGeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784740720; x=1785345520; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=cRQ5TWPONEvJdayuRFKl7W3Z0rghnTrzVVZ4y0zRgw0=; b=aTw8cIWL60l33XxzYi6B29Aour614OM8ipbbIRPznluqhNw1HsTi5dZ+wMiEE9Y+r9 4h/LcmkNe9RTGcF5MoYhpoM7r/70RdlQVGLoH0S2SZSlnHb8+h5ZsvOFnOIJsZMUwls+ Uq1wPSS0vbDoPJ67PocYelnMaR6IboQtcS0G1W+y3nhT0eOyugUoSgSeydS19eO6vB+I Z9OS7dywnYyyQRfcsnFjZmLmcQ+ZrA7fszlMffcLFGnIxEQcGuGj9GeEwFnZS4IzVojE jJ0TzZsYHtKfe90oo6i3Rxh21dN198Zsfuyl/Id456nuzBjZS3g/OxRkS/Ii/zNcA/tA m1zw== X-Forwarded-Encrypted: i=1; AHgh+Rpj6omcLdVHRPzePuaeXZJ1DcnlLhuXLYF2QtZuypUN9IjOp3Xr3uIyF7eu3cQdVKkgW3MjOcWfKtE0qno=@vger.kernel.org X-Gm-Message-State: AOJu0YxpjXybFehvOLvw4FxDjQgVYUJS9S5eXreN1f3j+QWuAx0+EfkT 8kZ7nEF2SZfM834oyPujIGNqumJNIbFO/w6KJsQk/eOU1ou1Zxouc/lM X-Gm-Gg: AR+sD11HniukLSfBRyhRWxX54M5CVeX9q8/+DlVHJXAoxq7YLawcTwuqgVFC3spUzUc GoDKIox2KAu0ieCOOq5LmNZJAzoC9nxciosv44oYeB5UpcNL7/Z71/h0vLUoT3prFmTno1rZvJP 2dmVDssZjQITMT+NeSOdAG5Z/RXSILdknoZhffZtfSFEUqcJybYPjkonwVCiHBe9xZld/e497uq oNolfXbn08YIREa4HeYahgE23ITNOCZad5uIlxmyq7RsTrL9ZVQFO66TENeg4nIHNVyxHxpg1em EfW7GbFc/rOLLc57iNkU35TMqfrRN681vB5DBdz6iooqNL4bFhsppJEOXNYjMMQA60qzO7TWhNC q9/yVSbUeEdrVewWGhSfnqe0MykKlrdLA9Sfuejr9ZHgFcX/E9W/f+1qqOpfTOgJ53nGgbDLKP9 SB0j8AIGtTH09jqI7X2RuoNGa5KwwK6QDU6VnlJCt/Tmc+ddL3Jtoq7skwe8aBWQlAPbRcbeNeD C0Ivannnkyc0csA/O/NFdQBwQamlit3IeE42lLv0/kKQwgw X-Received: by 2002:a05:600c:4f82:b0:495:6274:56bd with SMTP id 5b1f17b1804b1-495659881dfmr61794135e9.4.1784740719850; Wed, 22 Jul 2026 10:18:39 -0700 (PDT) Received: from L-022584.energy.envision.com (dynamic-078-051-150-230.78.51.pool.telefonica.de. [78.51.150.230]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4956a634cf9sm92427615e9.9.2026.07.22.10.18.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Jul 2026 10:18:39 -0700 (PDT) From: Xin Xie To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, horms@kernel.org, andrew+netdev@lunn.ch, qingfang.deng@linux.dev, shuah@kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Xin Xie , stable@vger.kernel.org Subject: [PATCH net 1/4] net: hsr: fix packet drops caused by GRO superpackets Date: Wed, 22 Jul 2026 19:18:33 +0200 Message-ID: <20260722171836.196-2-xiexinet@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260722171836.196-1-xiexinet@gmail.com> References: <20260722171836.196-1-xiexinet@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" HSR/PRP append a 6-byte tag/RCT to every forwarded frame and process each frame individually (sequence numbering, duplicate discard). When a lower device aggregates received frames into a GRO super-packet -- in software, or in hardware on GRO_HW-capable NICs -- the HSR receive/forward path mishandles it: frames are dropped and, on memory-constrained devices, processing super-skbs in softirq context can also pressure atomic memory allocation. The HSR/PRP stack already disables LRO on enslaved devices for the same reason. Extend that treatment to GRO: add netif_disable_gro() and dev_disable_gro() mirroring netif_disable_lro()/dev_disable_lro(), and call dev_disable_gro() from hsr_portdev_setup() so enslavement to an HSR/PRP master automatically strips NETIF_F_GRO and NETIF_F_GRO_HW on the lower device (recursively on its own lowers, as with LRO). Fixes: f421436a591d ("net/hsr: Add support for the High-availability Seamle= ss Redundancy protocol (HSRv0)") Cc: stable@vger.kernel.org Signed-off-by: Xin Xie --- include/linux/netdevice.h | 2 ++ net/core/dev.c | 18 ++++++++++++++++++ net/core/dev_api.c | 16 ++++++++++++++++ net/hsr/hsr_slave.c | 1 + 4 files changed, 37 insertions(+) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9981d637f..eba2c26a4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -3434,6 +3434,8 @@ void dev_close(struct net_device *dev); void netif_close_many(struct list_head *head, bool unlink); void netif_disable_lro(struct net_device *dev); void dev_disable_lro(struct net_device *dev); +void netif_disable_gro(struct net_device *dev); +void dev_disable_gro(struct net_device *dev); int dev_loopback_xmit(struct net *net, struct sock *sk, struct sk_buff *ne= wskb); u16 dev_pick_tx_zero(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev); diff --git a/net/core/dev.c b/net/core/dev.c index 5933c5dab..a6cf2adc8 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1840,6 +1840,24 @@ void netif_disable_lro(struct net_device *dev) } } =20 +void netif_disable_gro(struct net_device *dev) +{ + struct net_device *lower_dev; + struct list_head *iter; + + dev->wanted_features &=3D ~(NETIF_F_GRO | NETIF_F_GRO_HW); + netdev_update_features(dev); + + if (unlikely(dev->features & (NETIF_F_GRO | NETIF_F_GRO_HW))) + netdev_WARN(dev, "failed to disable GRO!\n"); + + netdev_for_each_lower_dev(dev, lower_dev, iter) { + netdev_lock_ops(lower_dev); + netif_disable_gro(lower_dev); + netdev_unlock_ops(lower_dev); + } +} + /** * dev_disable_gro_hw - disable HW Generic Receive Offload on a device * @dev: device diff --git a/net/core/dev_api.c b/net/core/dev_api.c index 437947dd0..02fb21629 100644 --- a/net/core/dev_api.c +++ b/net/core/dev_api.c @@ -269,6 +269,22 @@ void dev_disable_lro(struct net_device *dev) } EXPORT_SYMBOL(dev_disable_lro); =20 +/** + * dev_disable_gro() - disable Generic Receive Offload on a device + * @dev: device + * + * Disable Generic Receive Offload (GRO) on a net device. Must be + * called under RTNL. This is needed if received packets may be + * forwarded to another interface. + */ +void dev_disable_gro(struct net_device *dev) +{ + netdev_lock_ops(dev); + netif_disable_gro(dev); + netdev_unlock_ops(dev); +} +EXPORT_SYMBOL(dev_disable_gro); + /** * dev_set_promiscuity() - update promiscuity count on a device * @dev: device diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c index d9af9e65f..cefbbfbd5 100644 --- a/net/hsr/hsr_slave.c +++ b/net/hsr/hsr_slave.c @@ -170,6 +170,7 @@ static int hsr_portdev_setup(struct hsr_priv *hsr, stru= ct net_device *dev, if (res) goto fail_rx_handler; dev_disable_lro(dev); + dev_disable_gro(dev); =20 return 0; =20 --=20 2.43.0 From nobody Fri Jul 24 22:51:56 2026 Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C41B7421256 for ; Wed, 22 Jul 2026 17:18:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784740724; cv=none; b=q0gpjsetmIN1k7SZ5RKPIugWjawct69hLV/ZP4+3jj4z3gZr5UusAcyUexYBXOD3D9U67f2Qv/YPqEzTM8CaCPLR8d/3IsbCn5SiGhv+yJlBn2++Fj2WdpP3TcT0p3+JAo4lEHatcM7oLmbZTyRt7kS7+gph3MweoHf6Fpz/TXY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784740724; c=relaxed/simple; bh=cdxRSieBisfFr5FX5xnyrYTHsugWro9SEov6ZIA36qM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lXyr1mgxvpLs5bMkqTyl/+4e4tp/kA3r4VJrCyrUns/rv/K+hM16hLRlGIU6s2W88Ju0NSY84U7tHTYM7sELai+A06YeJoB3YDibbNIMZ3rVAR9NRQzg+yACmBjtOupK0gpyAkWtIZdAxL1nOcSWqF6biKOBM/J5z28IZQo1umI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KzgPcwgv; arc=none smtp.client-ip=209.85.221.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KzgPcwgv" Received: by mail-wr1-f42.google.com with SMTP id ffacd0b85a97d-47df6a5655aso625f8f.1 for ; Wed, 22 Jul 2026 10:18:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784740721; x=1785345521; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=BqxPzTHo4F6RITjff4xFH6QwEdtq0VyFnyAnj9pOhVQ=; b=KzgPcwgvZaup9SertoK4l/MgqNA1KVtYVQUW7bICsWpo5cFbFXSWdYydHsc3J+W88P qUaD4aqygZFKyu3z/vfRVxRIZd9mmx0Tp9jQcV4B7ibLrhQhp5ZurU4fx13UtdOTsAA0 XidGAIxnSkdI0FoejWwgqHvMOLx6gEHs2hKa8mzCPrIpqxnx9wQ8wqgcw3Jxq5QDhakf Akb69G5Ul69SYbr1Eh8fn2jqTpzD5C5jycaucSHQzgarivDqyvItAIMSt3dIkQ4H7wPl qqJPP6NX/r2RSnaEShb/nLRwwLpVKAjwy1xDzumOFvdf6YQi1KvVTdQi3tkbSV8Vdf/4 cflQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784740721; x=1785345521; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=BqxPzTHo4F6RITjff4xFH6QwEdtq0VyFnyAnj9pOhVQ=; b=RdDONimjzvegaI4W6GZmzCYLIJ8aa9anEtsbAPX9unADjwigEt8B4WqeT9h2LSxoc2 mxIsBEkbP6qE6AfoIcCczNOtvQLikWjnuJu83M36anaamXOPOa1Z/QulCA3XpE/bpUI2 Ok3LNZaTiMk2gYLuwyood1pfgOUGWwsOiHWiVK5M+Smo2BwerutrHqcGZl2k0eUQKPaF MgKthYJAdvup6WWZ2l44/GpPA3rEGkRCwH7dG1W3pKTNZkQtiM8kAjAZu68eVPMyMVEg kP0XTwsNZqHAZfWl12YNoARg0oan/chiPS5kLXzpn4D1Sd5FPtVo52U2WtFuQ8+yb1iC WPKg== X-Forwarded-Encrypted: i=1; AHgh+RpMR0wK3WzKOlLpzeJjb+CHTSOXJmvcx1CCIt/ew1rPYiPzElT97k03FnNLA2Jlo5mO1OGyOSfizFbLqzM=@vger.kernel.org X-Gm-Message-State: AOJu0YzbjUz0nWXbksdLAt0ucGhDNUYA58BaPA9NVkV+YWaEYd8V6I0Z mruzY17Qtb+29V8LIMviL2mloWgbLm78O978nTcSAXIumy4sx5pt9rai X-Gm-Gg: AR+sD10/5CD2W44r0t1TVsOjGO9fFqOOMM1W0djvRKLe2HwKtmqELlSihbG6eTPYNae PqdAX7icykYNIv9WQg2zUwp7lAaaukHleLmgrj7xB6/IXWYCyZuac7WByi/jDu83JFQr+jfBj/J UhVH1V2t/x1L+bJxfDyqaDMKCq1GdLka0iR8gB5erEziA5QTb1YvrRLDRV70vHhJkw+7d+UJRqW ++wIsElu97FdVXoZl9PDTiVRUhUWSbLTmSHcvas/RveT5ZEdxkVG7RtjoUuOWhdCPORpxewoIwi f3ImVm1v0o47FmGaR+hua/xAKWiRhMU1I2kg5gWN+E2vMv5AxkSqxl69pXKy4Gqy3TsVaNllYaY 1ArpZsZ5+C4fZF8gaN8XqA6nvIsUIr7hfcSILz2JTLO/7/+QP32tE2OC18fOYdVQHmRpCQ+1xMX 4t9wQHcSb4W+WN1vUV0aWFkSHDmEUm0VzG06vU/mUwFiKZw1Nz0xO4zYv0BwBUHs03IpZscuyzQ 5A9966H5MGNMBRxUuoI6jY5Y5ogz2/P27dJ9Q== X-Received: by 2002:a05:600c:1d1a:b0:493:e536:7bcf with SMTP id 5b1f17b1804b1-4956b012531mr29669095e9.7.1784740720971; Wed, 22 Jul 2026 10:18:40 -0700 (PDT) Received: from L-022584.energy.envision.com (dynamic-078-051-150-230.78.51.pool.telefonica.de. [78.51.150.230]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4956a634cf9sm92427615e9.9.2026.07.22.10.18.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Jul 2026 10:18:40 -0700 (PDT) From: Xin Xie To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, horms@kernel.org, andrew+netdev@lunn.ch, qingfang.deng@linux.dev, shuah@kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Xin Xie , stable@vger.kernel.org Subject: [PATCH net 2/4] net: hsr: shrink seqnr_lock to sequence counter updates Date: Wed, 22 Jul 2026 19:18:34 +0200 Message-ID: <20260722171836.196-3-xiexinet@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260722171836.196-1-xiexinet@gmail.com> References: <20260722171836.196-1-xiexinet@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" hsr->seqnr_lock is currently held across entire hsr_forward_skb() calls: master TX (hsr_dev_xmit()), interlink RX (hsr_handle_frame()), and both supervision frame builders hold it while frames are built, classified, duplicated and forwarded on every port. The only state that actually needs the lock is the sequence counters themselves (hsr->sequence_nr / hsr->sup_sequence_nr). Shrink the locking to the individual counter updates: handle_std_frame() now takes the lock around its sequence number allocation (replacing the lockdep assertion), the master TX and interlink RX paths drop their outer lock, and the supervision builders release the lock right after updating their counter instead of holding it across frame construction and forwarding. Sequence numbers remain unique and monotonically allocated per counter; concurrent inputs may now interleave allocations, which is fine as the output paths were already concurrent. This is a prerequisite for unfolding GSO super-packets at the forward entry: segmentation with its dozens of GFP_ATOMIC allocations must not run with BH disabled under the global sequence lock. The locking being narrowed here was introduced by 06afd2c31d33 ("hsr: Synchronize sending frames to have always incremented outgoing seq nr."), briefly removed by b3c9e65eb227 ("net: hsr: remove seqnr_lock") and reinstated for the interlink RX path by 430d67bdcb04 ("net: hsr: Use the seqnr lock for frames received via interlink port.") after a syzbot lockdep report. All sequence counter updates remain protected; only the forwarding work moves out of the critical section. Cc: stable@vger.kernel.org Signed-off-by: Xin Xie --- net/hsr/hsr_device.c | 15 ++++----------- net/hsr/hsr_forward.c | 3 ++- net/hsr/hsr_slave.c | 11 +---------- 3 files changed, 7 insertions(+), 22 deletions(-) diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 5555b71ab..3fd1762d8 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -232,9 +232,7 @@ static netdev_tx_t hsr_dev_xmit(struct sk_buff *skb, st= ruct net_device *dev) skb->dev =3D master->dev; skb_reset_mac_header(skb); skb_reset_mac_len(skb); - spin_lock_bh(&hsr->seqnr_lock); hsr_forward_skb(skb, master); - spin_unlock_bh(&hsr->seqnr_lock); } else { dev_core_stats_tx_dropped_inc(dev); dev_kfree_skb_any(skb); @@ -335,6 +333,7 @@ static void send_hsr_supervision_frame(struct hsr_port = *port, hsr_stag->sequence_nr =3D htons(hsr->sequence_nr); hsr->sequence_nr++; } + spin_unlock_bh(&hsr->seqnr_lock); =20 hsr_stag->tlv.HSR_TLV_type =3D type; /* HSRv0 has 6 unused bytes after the MAC */ @@ -356,14 +355,10 @@ static void send_hsr_supervision_frame(struct hsr_por= t *port, ether_addr_copy(hsr_sp->macaddress_A, hsr->macaddress_redbox); } =20 - if (skb_put_padto(skb, ETH_ZLEN)) { - spin_unlock_bh(&hsr->seqnr_lock); + if (skb_put_padto(skb, ETH_ZLEN)) return; - } =20 hsr_forward_skb(skb, port); - spin_unlock_bh(&hsr->seqnr_lock); - return; } =20 static void send_prp_supervision_frame(struct hsr_port *master, @@ -390,6 +385,7 @@ static void send_prp_supervision_frame(struct hsr_port = *master, spin_lock_bh(&hsr->seqnr_lock); hsr_stag->sequence_nr =3D htons(hsr->sup_sequence_nr); hsr->sup_sequence_nr++; + spin_unlock_bh(&hsr->seqnr_lock); hsr_stag->tlv.HSR_TLV_type =3D PRP_TLV_LIFE_CHECK_DD; hsr_stag->tlv.HSR_TLV_length =3D sizeof(struct hsr_sup_payload); =20 @@ -397,13 +393,10 @@ static void send_prp_supervision_frame(struct hsr_por= t *master, hsr_sp =3D skb_put(skb, sizeof(struct hsr_sup_payload)); ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr); =20 - if (skb_put_padto(skb, ETH_ZLEN)) { - spin_unlock_bh(&hsr->seqnr_lock); + if (skb_put_padto(skb, ETH_ZLEN)) return; - } =20 hsr_forward_skb(skb, master); - spin_unlock_bh(&hsr->seqnr_lock); } =20 /* Announce (supervision frame) timer function diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c index 0774981a6..8e4158a9b 100644 --- a/net/hsr/hsr_forward.c +++ b/net/hsr/hsr_forward.c @@ -621,9 +621,10 @@ static void handle_std_frame(struct sk_buff *skb, if (port->type =3D=3D HSR_PT_MASTER || port->type =3D=3D HSR_PT_INTERLINK) { /* Sequence nr for the master/interlink node */ - lockdep_assert_held(&hsr->seqnr_lock); + spin_lock_bh(&hsr->seqnr_lock); frame->sequence_nr =3D hsr->sequence_nr; hsr->sequence_nr++; + spin_unlock_bh(&hsr->seqnr_lock); } } =20 diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c index cefbbfbd5..c7fd021f0 100644 --- a/net/hsr/hsr_slave.c +++ b/net/hsr/hsr_slave.c @@ -73,16 +73,7 @@ static rx_handler_result_t hsr_handle_frame(struct sk_bu= ff **pskb) } skb_reset_mac_len(skb); =20 - /* Only the frames received over the interlink port will assign a - * sequence number and require synchronisation vs other sender. - */ - if (port->type =3D=3D HSR_PT_INTERLINK) { - spin_lock_bh(&hsr->seqnr_lock); - hsr_forward_skb(skb, port); - spin_unlock_bh(&hsr->seqnr_lock); - } else { - hsr_forward_skb(skb, port); - } + hsr_forward_skb(skb, port); =20 finish_consume: return RX_HANDLER_CONSUMED; --=20 2.43.0 From nobody Fri Jul 24 22:51:56 2026 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8AA244F7994 for ; Wed, 22 Jul 2026 17:18:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784740726; cv=none; b=a3VHXrfghDTy+1G/Mr40IOUL2VqJnLbGrkUFseD6tNuidnJ+DcLoZYd9Jn72fCtzC6ywGTSrdVwgpII1v5ZV80YgTM6hwsvkAo5Uvn8STsgni/aWxUdYu4E7B16lH221f3ZbKcCa1sjeXfcPl/2EUKt807kNamFtG8VTc1KWo7I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784740726; c=relaxed/simple; bh=o/Bu15sDhEOsKHR4CQblrys7TkwgkSC18uEGHD2BjAI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kieljL/XZrmpVjFgXSSZQasCXn0yXoXLBHN73rl9yRqCar8OgNEZJvt7SlPrQYRvFuB/JuvZofpr0C4LslwICoSlirewff5r8p57WehWSfL0t8CJFdZFhXKeNDhPcrCj9s9uDx+DgeXwXWmOvayE9hdcepdBKqV3KZUZ026sAeY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=dMDqjuAx; arc=none smtp.client-ip=209.85.128.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="dMDqjuAx" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-49544f26c43so117335e9.0 for ; Wed, 22 Jul 2026 10:18:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784740723; x=1785345523; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Bgp1uL2zdCSwtHxWPjmVsr5a9ctDEumlGTtccTCWom4=; b=dMDqjuAxJvWvIZ7JSGFL7ZOA621OxDc/HgzQm5UVxJl3/TTnfzzdC6CXniY45fMsyE 8l1X3cYnB2ydjPu8gk3Ixlpd5+N8XM+1g2jD+bvKoETcwI6fCvNhohe3x5q7bnK6rrgM xpEwqAysgz2ZEhviGR2a+vZosOXCXKPszaqHru8xn/YH9F4yXPeU3G3ZyprIpdO3Rdzx dmRJGirqQkR/5xGFRV0MbsIGveS3RC8KacGRfdcEDlC5LtEQJccGbwp5LFKR18o/8p+x 7sypXEHo9xuSmxrdCpp2p7etbCf+RrMRQIPLH68Og2KvDVZtapILo/7Hlu192Lh4E/jU pYAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784740723; x=1785345523; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Bgp1uL2zdCSwtHxWPjmVsr5a9ctDEumlGTtccTCWom4=; b=pqnRs6gUsOpzG5WDZsyMufe7HznM5cBejAhiIvoFB0AQa660T5SX6TCiQwtTgxV90O OjDH11v63ISi0UPt2aySaaKID7Ay7AH0eDJzhPwbvMeo+CfvCEli+n8lM2lAMYi/ZTOl 0C4Z8tBBd8FZG1hCfAt7APZRPdremanKZ5mf435OxD5k5nv3pUpRw6GhfqB2oCL23HG2 0EbbrupRQuAkGFuKBVbfjRWVvnKCmSMEFdKAM+GZCAKBrBNNDdc1iOgQ06SdV+1y6YUP TfVfyt+8oW2BV3NZVooESF6lcqjEmRtQuXX/qWnLuW1uGSRDbjKLBV3L3hOqXxLwD9lh Sfqw== X-Forwarded-Encrypted: i=1; AHgh+RqpuLzjFi39NYHeqHZbjyRYDJx+W+OBtzks0Avky3RM5/QXPf8HL3dDptX07vhgMV211yrUZc4fS+xXFvg=@vger.kernel.org X-Gm-Message-State: AOJu0Yww3GrO9qctgjbO3OhW6PUNBhNl9dig78VSj0oXMnX2ikUcM/K7 VSqleg6cspOCHIOcB2fyPkmN/DU5fEs1flai66lRnjP/aGUqTILljoF8 X-Gm-Gg: AR+sD11ehfJmXTkLtH7eaosjb1fz/WzeDWqacpYMXCGlMQd0SL5+6VPjeM4O4uvUF0P IcY8dJlcn9QE6Ov06mIkAR/5t+Jx8JNZUx0QnqIuUZNQn7jxuIrVF7orNjswPZoQ5wqbQwiOyE0 w3IgWzfZNUi4Mv6buNnNExuWdGgPNp49wQ1D/RYm+euxp2bVkTp7fGcJVxp8dIWHTVlQrpRsx8l 5RySdnzE+hGx2uHw1Wp00GiPKyuMIghXHscefTJ23mnqXdb7wJdmipTn0TBWUt5fN/hxFjvMUyL K4Cg7a2k9/dyhu9CMNdCZx5JCE7Msw0Urf/Bg7MKyUXfCOWw0XgQCZz73A3b45KzscmWIueBceY e8m6RHrZEFF5QAm1pEjCJugGjYKva7BpW9vW1dx5u19/X1J6kBKVbEsO3Q1spcmvGFBMQLtHvsO 7dVH3kb7gwkrNhBxWrRxEWUNuk/pzHGHhGdlP4iJfswHkqjb0BMrRLEAUfOdZ3T4l8BlKhOD2T8 GTwyjNncSOUm9Of35xcZAjVY/ALfL35glkOgVmJMC01BC2b X-Received: by 2002:a05:600c:4584:b0:495:6713:9ae2 with SMTP id 5b1f17b1804b1-4956713a250mr56348975e9.1.1784740722310; Wed, 22 Jul 2026 10:18:42 -0700 (PDT) Received: from L-022584.energy.envision.com (dynamic-078-051-150-230.78.51.pool.telefonica.de. [78.51.150.230]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4956a634cf9sm92427615e9.9.2026.07.22.10.18.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Jul 2026 10:18:41 -0700 (PDT) From: Xin Xie To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, horms@kernel.org, andrew+netdev@lunn.ch, qingfang.deng@linux.dev, shuah@kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Xin Xie , stable@vger.kernel.org Subject: [PATCH net 3/4] net: hsr: unfold GSO super-packets at the forward entry Date: Wed, 22 Jul 2026 19:18:35 +0200 Message-ID: <20260722171836.196-4-xiexinet@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260722171836.196-1-xiexinet@gmail.com> References: <20260722171836.196-1-xiexinet@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" HSR/PRP forward frames one by one: each wire frame gets its own tag and sequence number, and duplicate discard is per frame. A GSO super-packet reaching hsr_forward_skb() breaks that per-frame semantics: it would be tagged and forwarded as a single frame. Unfold such super-packets at the forward entry with the top-level GSO dispatch: __skb_gso_segment() initializes SKB_GSO_CB() and performs the L2->L3->L4 protocol dispatch (calling the low-level skb_segment() helper directly is not allowed here -- it reads SKB_GSO_CB(skb) state that only __skb_gso_segment() sets up). features =3D 0 requests full software segmentation; tx_path is selected by ingress port (master =3D locally generated TX, interlink =3D RX) to get the right checksum semantics. Each segment then runs through the existing per-frame path, which is split out as hsr_forward_skb_one() so that no GSO skb can reach it. Segmentation is only offered for the ingress roles whose frames are known to be plain Ethernet: the master (locally generated) and the interlink (SAN side, untagged). A super-packet received from a LAN slave may carry per-frame HSR tags or PRP RCT trailers that software segmentation cannot recover, and an already-tagged HSR/PRP super-packet violates per-frame wire semantics; both are rejected by ingress-port policy. (ETH_P_PRP identifies supervision traffic only; a PRP data frame keeps its payload EtherType, so RCT carriage cannot be tested by protocol.) Also drop NETIF_F_GSO_MASK from the HSR master's hw_features so locally generated traffic is segmented before reaching the forward path whenever possible. Fixes: f421436a591d ("net/hsr: Add support for the High-availability Seamle= ss Redundancy protocol (HSRv0)") Cc: stable@vger.kernel.org Signed-off-by: Xin Xie --- net/hsr/hsr_device.c | 2 +- net/hsr/hsr_forward.c | 50 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 3fd1762d8..248cbb142 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -652,7 +652,7 @@ void hsr_dev_setup(struct net_device *dev) dev->needs_free_netdev =3D true; =20 dev->hw_features =3D NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | - NETIF_F_GSO_MASK | NETIF_F_HW_CSUM | + NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_FILTER; =20 diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c index 8e4158a9b..3fcdbac49 100644 --- a/net/hsr/hsr_forward.c +++ b/net/hsr/hsr_forward.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "hsr_main.h" #include "hsr_framereg.h" =20 @@ -732,7 +733,7 @@ static int fill_frame_info(struct hsr_frame_info *frame, } =20 /* Must be called holding rcu read lock (because of the port parameter) */ -void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port) +static void hsr_forward_skb_one(struct sk_buff *skb, struct hsr_port *port) { struct hsr_frame_info frame; =20 @@ -761,3 +762,50 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_p= ort *port) port->dev->stats.tx_dropped++; kfree_skb(skb); } + +/* GSO fan-out funnel: unfold super-packets before per-frame processing so + * each wire frame gets its own HSR/PRP tag and sequence number. + */ +void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port) +{ + struct sk_buff *segs, *next; + + if (likely(!skb_is_gso(skb))) { + hsr_forward_skb_one(skb, port); + return; + } + + /* Unfold only plain-Ethernet GSO super-packets: locally generated + * on the master, or arriving untagged from the SAN side on the + * interlink. A super-packet from a LAN slave may carry per-frame + * HSR tags / PRP RCT trailers that software segmentation cannot + * recover; an already-tagged HSR/PRP super-packet violates + * per-frame wire semantics. Drop both. + */ + if (port->type !=3D HSR_PT_MASTER && port->type !=3D HSR_PT_INTERLINK) + goto drop_gso; + if (skb->protocol =3D=3D htons(ETH_P_HSR) || + skb->protocol =3D=3D htons(ETH_P_PRP)) + goto drop_gso; + + /* features =3D 0: request full software segmentation. tx_path is true + * only for locally generated traffic on the master; ingress from + * the interlink follows RX checksum semantics. + */ + segs =3D __skb_gso_segment(skb, 0, port->type =3D=3D HSR_PT_MASTER); + if (IS_ERR(segs) || unlikely(!segs)) + goto drop_gso; + + consume_skb(skb); + while (segs) { + next =3D segs->next; + segs->next =3D NULL; + hsr_forward_skb_one(segs, port); + segs =3D next; + } + return; + +drop_gso: + port->dev->stats.tx_dropped++; + kfree_skb(skb); +} --=20 2.43.0 From nobody Fri Jul 24 22:51:56 2026 Received: from mail-wr1-f48.google.com (mail-wr1-f48.google.com [209.85.221.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA63F345EBF for ; Wed, 22 Jul 2026 17:18:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784740728; cv=none; b=ObroIyChbaP7dp2N/vhsHQS//IH0hgtkMKD+M+7g5PwQL2vWwjeCVwuOaCKEtisCyuztMt8Y7LtejCJVkkrEKQ7b0E8xJ0wnk/PVRUzrdcZ7ICFNh+D/SYOFdbTicYhXqtJ6RZn+a5ovPURDI502jy3ANcuPrBlF8erf7sG0tIk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784740728; c=relaxed/simple; bh=fYv45bTPv6rAMHoRjWxrBRIGiABY1LmdMqeDqcUiphw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FM7UX+NWE47agp7Wzsx+rijFNcVT7L5fN2/1wjUNSPf3KoILR2HkjWqFmLU9l5usxAYXHQIrZAPTuWChyk84amwpnvj9Ns3bOIUS8ksdd/nk6CDBXw5T5CKEEziniD6CKOu4xLOuFgfUJXfj3h5JALeBp84SIkHPQC3KCocZj8E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=GdTjZCba; arc=none smtp.client-ip=209.85.221.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GdTjZCba" Received: by mail-wr1-f48.google.com with SMTP id ffacd0b85a97d-47df6a5655aso633f8f.1 for ; Wed, 22 Jul 2026 10:18:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784740724; x=1785345524; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=GyvSsqSpfDY2oL4Eym940bEubjIgZeaLaQ/eKflDksk=; b=GdTjZCba953/cGR2jTcsRE2Y44y8ct7FNg+3Rpgs9YDghvfMDUmQbBP+qe3iG2o+1+ wska4UVnVSWn4uYq0kr9V/yt48tdPyMQ74mjxJSZizkUlA4Dh+h1kFUUbyS2lGKto9X9 YD4bu4TcsRcG5D6AIK8BuvT1IKzkYU8/1qmvzT1ZdfSUw1rldwsykSB3/5yVFpG1hRm7 IfwLSiKwcLNUk75pI7AvafeqWTPrIgkcPuvfz/dePc3/e1WPI9hJf+7OYebFSW+VGID2 b2TixbhqD6tzMAi/FOvLgUc5ImjEEfWR89SHUntlIW4GSreiLydIQL9ONTQTSVKe7+cZ c7AQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784740724; x=1785345524; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=GyvSsqSpfDY2oL4Eym940bEubjIgZeaLaQ/eKflDksk=; b=CYCFKiZxXr6ZNjyJxXNU4fQLGTFIvs/998jUO5CWdDKNvUITCmXvak0vBkN8o4EpUX VQnUKudiPDj0P4N4ObouhxFZayQxp0Tex0G0WFdegqqP5HadM9MQPYCskkEsJnUbBTfH oz8BWYwDoiizGlpawlGl8iOPS1kKwfBH9YVv9QTZmINw3TQ+6LTburNwJSXK6JROPu71 ieD82pWO+LsccpcMceRya7Oz2MNCwZtajq4AHkY/1eLwN+msH4e+Q5zPcLTj1rEzyCzG fgzMdL5rm8GQWKKw18V4B83htppLzA2wdDbm2GX31re4rZ7rueXxalLUDybZq5GIf35b TU7g== X-Forwarded-Encrypted: i=1; AHgh+RoHki90sHXyKDhvjaJf2jLG0+GHXkWie2ta64JzaFfo0wCuezIBFtNEI/E7ILLAztUoa2chzCHP1z5SUuo=@vger.kernel.org X-Gm-Message-State: AOJu0Yz4uiroSF4LCaM4QC3CGQSsbWHAo+Pkqr/WZFjl4Dn/Cgm5NTQM wT9eqB00srL4xVo+Ku3AQAZ/FE05RO2xuX0AkkiujxQrxU0h0knlOtGY X-Gm-Gg: AR+sD10fgbGnW7m0byEW5tibjLCkxvbjhy/pGIk5yjWUOLYRYuZPQDPtbrj7WWMaQ2x +xmX7KLc6kfgHxwMTvphI8eYR0oQw+2NEk0ecWIPWO1R0GEdSuFHpzX9Ej5X4v2c7N2w2nY0HME TPc7IfRDMj6Ura2PzautIYwdfB9rWj/ukWSrf38U6+r0IJTv3MRsiK54A9TjUEPZse1CuizZwNb 4m8CKErZQRDD3EGC7pGmX2jmn/yMg79QQhVnPIdHmoTm9/O4y1nRZVY0MUiW3UQtjTLUOd5geOA JEdoKyQPIb6YUv5lKFIP+7yfFZ/8ID+OLjnTnTq3Vfu73uw4s056YTZtMeT2Ac6HObQbaagBIMA s5doEPKCHcU/m36077MvJ0dLIUz8gNUGOmFTg2PEWFaNpzMaaqTtqICA/XjbqWlrX7b7W+57Os/ hstVKMvuR3PAjmhpXPsIXSoi6x3jwBxjgKWGCftZQEkJA4h4DFF/DccTVkuoZyzzJIDL3tqr8qy sVfM8NGUkcI2+WrE7f+c80QyvHEvkg+Bvp2Fg== X-Received: by 2002:a05:600c:8519:b0:493:fe47:d528 with SMTP id 5b1f17b1804b1-4956b01263cmr28636635e9.8.1784740723521; Wed, 22 Jul 2026 10:18:43 -0700 (PDT) Received: from L-022584.energy.envision.com (dynamic-078-051-150-230.78.51.pool.telefonica.de. [78.51.150.230]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4956a634cf9sm92427615e9.9.2026.07.22.10.18.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Jul 2026 10:18:43 -0700 (PDT) From: Xin Xie To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, horms@kernel.org, andrew+netdev@lunn.ch, qingfang.deng@linux.dev, shuah@kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Xin Xie Subject: [PATCH net 4/4] selftests: net: hsr: add GRO super-packet forwarding test Date: Wed, 22 Jul 2026 19:18:36 +0200 Message-ID: <20260722171836.196-5-xiexinet@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260722171836.196-1-xiexinet@gmail.com> References: <20260722171836.196-1-xiexinet@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a test exercising the HSR forward path with GSO super-packets: a TSO-enabled SAN behind the interlink streams TCP through an HSR DUT to a peer node. The test verifies that: * enslaved devices have GRO and HW-GRO disabled automatically, * the HSR master does not advertise GSO/TSO features, * the stream completes with zero retransmits, i.e. super-packets are unfolded per-frame at the forward entry instead of being tagged and forwarded as single oversized frames (the stream is rate-capped so the zero-retransmit discriminator is stable on CI-class hosts). The one-shot iperf3 server runs inside a wrapper shell with its exact PID recorded (pidfile appearance is polled, no startup race): cleanup kills the server and wait(1)s the wrapper on every exit path, and the success path waits and checks the server exit status, so neither the server process nor the namespaces can leak. Environments whose iproute2 lacks the HSR interlink syntax are skipped with ksft_skip. Without the fixes the feature checks fail, and on drivers that hand GRO super-packets to the HSR receive path the stream degrades or stalls. Signed-off-by: Xin Xie --- tools/testing/selftests/net/hsr/Makefile | 1 + .../selftests/net/hsr/hsr_gro_superpacket.sh | 249 ++++++++++++++++++ 2 files changed, 250 insertions(+) create mode 100755 tools/testing/selftests/net/hsr/hsr_gro_superpacket.sh diff --git a/tools/testing/selftests/net/hsr/Makefile b/tools/testing/selft= ests/net/hsr/Makefile index 31fb9326c..0d105476e 100644 --- a/tools/testing/selftests/net/hsr/Makefile +++ b/tools/testing/selftests/net/hsr/Makefile @@ -3,6 +3,7 @@ top_srcdir =3D ../../../../.. =20 TEST_PROGS :=3D \ + hsr_gro_superpacket.sh \ hsr_ping.sh \ hsr_redbox.sh \ link_faults.sh \ diff --git a/tools/testing/selftests/net/hsr/hsr_gro_superpacket.sh b/tools= /testing/selftests/net/hsr/hsr_gro_superpacket.sh new file mode 100755 index 000000000..4b0a9ceea --- /dev/null +++ b/tools/testing/selftests/net/hsr/hsr_gro_superpacket.sh @@ -0,0 +1,249 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test HSR handling of GRO/GSO super-packets: +# +# 1. Enslaving a device to an HSR master disables GRO on it +# (dev_disable_gro()). +# 2. The HSR master does not advertise GSO/TSO features. +# 3. A TCP stream from a TSO-enabled SAN (which therefore emits GSO +# super-packets) is unfolded at the HSR forward entry and delivered +# per-frame: the transfer completes with zero retransmits. +# +# Topology (100.64.0.0/24): +# +# ns_san ns_dut ns_peer +# +-----------+ interlink +---------------+ LAN A/B +-----------+ +# | s0 [0.1] |-------------| d_il hsr0 |-----------| hsr1 [0.3]| +# +-----------+ | d_a / d_b | | p_a / p_b | +# +---------------+ +-----------+ +# +# SAN traffic reaches ns_peer only through hsr0's forward path +# (interlink RX -> LAN A/B TX), so every SAN frame is tagged and +# forwarded by the DUT. + +source ./hsr_common.sh + +ns_dut=3D"hsr-gro-dut" +ns_san=3D"hsr-gro-san" +ns_peer=3D"hsr-gro-peer" +san_ip=3D"100.64.0.1" +peer_ip=3D"100.64.0.3" +iperf_pid=3D"" +server_wrapper=3D"" +iperf_pidfile=3D"/tmp/hsr_gro_iperf.pid" + +cleanup() +{ + if [ -n "${iperf_pid}" ] && [[ "${iperf_pid}" =3D~ ^[0-9]+$ ]]; then + kill "${iperf_pid}" 2>/dev/null + fi + if [ -n "${server_wrapper}" ]; then + # the wrapper waits on the server; reap it with a 5s bound so a + # live-but-unpublished server can never hang cleanup + for _ in $(seq 1 50); do + kill -0 "${server_wrapper}" 2>/dev/null || break + sleep 0.1 + done + kill "${server_wrapper}" 2>/dev/null + wait "${server_wrapper}" 2>/dev/null + server_wrapper=3D"" + fi + # last resort, namespace-scoped only: kill iperf3 processes that + # actually live in the peer netns. netns !=3D pidns: a blind pkill + # would scan the host PID space and hit unrelated tests. + for _p in $(ip netns pids "$ns_peer" 2>/dev/null); do + if [ "$(cat /proc/$_p/comm 2>/dev/null)" =3D "iperf3" ]; then + kill "$_p" 2>/dev/null + fi + done + iperf_pid=3D"" + rm -f "${iperf_pidfile}" + ip netns del "$ns_dut" 2>/dev/null + ip netns del "$ns_san" 2>/dev/null + ip netns del "$ns_peer" 2>/dev/null +} + +trap cleanup EXIT + +check_tool() +{ + if ! command -v "$1" > /dev/null 2>&1; then + echo "SKIP: Could not run test without $1" + exit $ksft_skip + fi +} + +nsx() +{ + ip netns exec "$1" bash -c "$2" +} + +setup_topo() +{ + local ns + + cleanup + for ns in "$ns_dut" "$ns_san" "$ns_peer"; do + ip netns add "$ns" + done + + ip link add d_a netns "$ns_dut" type veth peer name p_a netns "$ns_peer" + ip link add d_b netns "$ns_dut" type veth peer name p_b netns "$ns_peer" + ip link add d_il netns "$ns_dut" type veth peer name s0 netns "$ns_san" + + # HSR tags add 6 bytes per frame; give the LAN legs headroom. + for iface in d_a d_b; do + nsx "$ns_dut" "ip link set $iface mtu 1600; ip link set $iface up" + done + for iface in p_a p_b; do + nsx "$ns_peer" "ip link set $iface mtu 1600; ip link set $iface up" + done + + nsx "$ns_dut" "ip link set d_il up" + nsx "$ns_san" "ip link set s0 up; ip addr add $san_ip/24 dev s0" + + nsx "$ns_dut" "ip link add hsr0 type hsr \ + slave1 d_a slave2 d_b interlink d_il proto 0; \ + ip link set hsr0 up" + nsx "$ns_peer" "ip link add hsr1 type hsr \ + slave1 p_a slave2 p_b proto 0; \ + ip link set hsr1 up; ip addr add $peer_ip/24 dev hsr1" + + # Let the nodes see each other's supervision frames. + sleep 2 +} + +check_feature() +{ + local ns=3D"$1" + local iface=3D"$2" + local feature=3D"$3" + local want=3D"$4" + + if nsx "$ns" "ethtool -k $iface" | grep -q "^$feature: $want"; then + echo "INFO: $ns/$iface $feature is $want [ OK ]" + else + echo "FAIL: $ns/$iface $feature is not $want" 1>&2 + ret=3D1 + fi +} + +do_gro_feature_checks() +{ + echo "INFO: Checking that enslavement disabled GRO." + check_feature "$ns_dut" d_a generic-receive-offload off + check_feature "$ns_dut" d_b generic-receive-offload off + check_feature "$ns_dut" d_il generic-receive-offload off + stop_if_error "GRO not disabled on enslaved devices." + + echo "INFO: Checking that enslavement disabled HW-GRO." + check_feature "$ns_dut" d_a rx-gro-hw off + check_feature "$ns_dut" d_b rx-gro-hw off + check_feature "$ns_dut" d_il rx-gro-hw off + stop_if_error "HW-GRO not disabled on enslaved devices." + + echo "INFO: Checking that the HSR master does not advertise GSO/TSO." + check_feature "$ns_dut" hsr0 generic-segmentation-offload off + check_feature "$ns_dut" hsr0 tcp-segmentation-offload off + stop_if_error "HSR master still advertises GSO/TSO." +} + +start_iperf_server() +{ + # One-shot server, no -D: record its exact PID (netns shares the PID + # namespace). The wrapping shell waits on the server so the script can + # really wait(1) for the whole tree, on success and failure alike. + rm -f "${iperf_pidfile}" + ( nsx "$ns_peer" "iperf3 -s -1 > /dev/null 2>&1 & echo \$! > ${iperf_pidf= ile}; wait" ) & + server_wrapper=3D$! + # the wrapper writes the pidfile asynchronously; wait for it to + # appear instead of racing the read + for _ in $(seq 1 50); do + [ -s "${iperf_pidfile}" ] && break + sleep 0.1 + done + if [ ! -s "${iperf_pidfile}" ]; then + echo "FAIL: iperf3 server did not publish a pid (no pidfile)" 1>&2 + ret=3D1 + return 1 + fi + iperf_pid=3D$(cat "${iperf_pidfile}") + if ! [[ "${iperf_pid}" =3D~ ^[0-9]+$ ]] || ! kill -0 "${iperf_pid}" 2>/de= v/null; then + echo "FAIL: iperf3 server pid '${iperf_pid}' invalid or not alive" 1>&2 + ret=3D1 + return 1 + fi + sleep 1 + return 0 +} + +do_tso_stream_test() +{ + local out sender_retr + + echo "INFO: Enabling TSO/GSO on the SAN interface." + nsx "$ns_san" "ethtool -K s0 tso on gso on" + check_feature "$ns_san" s0 tcp-segmentation-offload on + stop_if_error "Could not enable TSO on the SAN interface." + + echo "INFO: Running 10s TCP stream SAN -> peer through the HSR DUT." + start_iperf_server || return + # rate-capped: the discriminator is per-frame unfold (completion with + # 0 retransmits), not max throughput; uncapped runs flap at VM/CI + # edge rates without indicating a functional problem. + out=3D$(nsx "$ns_san" "timeout 60 iperf3 -c $peer_ip -M 1446 -b 2G -t 10"= 2>&1) + if [ $? -ne 0 ]; then + echo "FAIL: iperf3 client failed:" 1>&2 + echo "$out" 1>&2 + ret=3D1 + return + fi + + # success path: the one-shot server exits by itself; really wait for + # the wrapper to reap it, and check its exit status + wait "${server_wrapper}" + server_rc=3D$? + server_wrapper=3D"" + iperf_pid=3D"" + if [ "$server_rc" -ne 0 ]; then + echo "FAIL: iperf3 server exited with rc=3D$server_rc" 1>&2 + ret=3D1 + return + fi + + sender_retr=3D$(echo "$out" | awk '/sender/ {print $(NF-1)}') + if [ -z "$sender_retr" ] || [ "$sender_retr" -ne 0 ]; then + echo "FAIL: retransmits during GSO unfold: ${sender_retr:-unknown}" 1>&2 + echo "$out" 1>&2 + ret=3D1 + return + fi + + echo "INFO: TCP stream completed with 0 retransmits [ OK ]" + echo "$out" | grep -E "sender|receiver" +} + +check_prerequisites +check_tool ethtool +check_tool iperf3 +check_tool timeout + +# iproute2 must know the HSR interlink syntax. +if ! ip link help hsr 2>&1 | grep -qi interlink; then + echo "SKIP: iproute2 has no HSR interlink support" + exit $ksft_skip +fi + +setup_topo + +echo "INFO: Initial validation ping (SAN -> peer through the DUT)." +do_ping "$ns_san" "$peer_ip" +stop_if_error "Initial validation failed." + +do_gro_feature_checks +do_tso_stream_test +stop_if_error "GSO super-packet stream test failed." + +echo "INFO: All good." +exit $ret --=20 2.43.0