From nobody Thu Apr 9 07:15:26 2026 Received: from mail-pj1-f50.google.com (mail-pj1-f50.google.com [209.85.216.50]) (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 D59FE363C58 for ; Tue, 10 Mar 2026 07:46:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773128818; cv=none; b=BI/szhg/F6YFlrC6Q4wRAx07lhEZEBty9cxV0PO676x1gDhU1MDVG+3hvCYs388Ig0CK+oX/GSuHDsfbzeqdYdnfzcbJ/GKjfKBNfdzhgrOBGTZznN5BcNoyNAKpflfizyTLWdCEqfftPrWdckqcFx8AcSa14H3ztYme3uNl5RU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773128818; c=relaxed/simple; bh=o63DNLwMJ9dnH9VRG7yBQJ58q0sgrk58BDknwrX9fmY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N2K25lVe6a1NH2oTFnvgl1tAp0999Ax86ToYIFqb2LTdHM2/2EnLeatTRcykojkin2prijXUZbc+O6QPIea8a9ILuJLXtXERDQWIXQuKMA47EMkQEQZbS3FrMR9oK/md0SfU0qs/aRbmsbdFTmKb7EsuRkPb6qpBc4A3nokUWLc= 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=ayD+6jEq; arc=none smtp.client-ip=209.85.216.50 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="ayD+6jEq" Received: by mail-pj1-f50.google.com with SMTP id 98e67ed59e1d1-3598c1ad542so5583251a91.0 for ; Tue, 10 Mar 2026 00:46:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773128814; x=1773733614; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=ZszkswRmv7zKXo3BtgB+URbNhojevOx1NtYtxreOH/Y=; b=ayD+6jEqXAwFT3qihwGehyMF6KA77cxiOHOT27j9yTl063cDtkiu1kHNZOf05mBIVb lShaWhgkxsh+F6MyIiiI1rVBrEzREQc6nt7XsQHYZM4mCdlLcVyAIzNqrT7ENXWyVNs9 ZCBxo4WD/RukRV6Be07Mse9obZavWyAdnOZBs3p88m7r92xvL/TTj5o7WhB2CDcIqmtj 582ogt+ZxQ7WXdbgE5bHI+FjnKQmSykB5IqN3UOSRHAitO8v3LbmBHcdFkPrphbsnzp1 yO/DqHG8bnikiz5GPD0E1eedabn8GoXIVU62keqL0fnbDZ1S3/bEbvOR6Vjhn5o/xt5a jNfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773128814; x=1773733614; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=ZszkswRmv7zKXo3BtgB+URbNhojevOx1NtYtxreOH/Y=; b=Wm0Q3m4T9NwiOp7QllBV2wxHQ2LKVdfDYe9aPUCFWTLXXfa7jQAvh2uFzZg6zx9LNg sfWijndjOjAOEb6XjO/jC4WKmZIE44OeLGmIy4bMxIQhmuah76nih2B43oAau9T2koRs 3bVD6XyOM+X3nhD0NNoiFsCAW4qcXr8LXQ8BPIq3UgxX97oqCIOJwRRvoR0hcg9+sPJY lTBF1IjBKv0FCSpGZwcUK1aclJpQPzg2Nv1tDLPHmmfbvKEPCl0PGyVUK8NK97XJVhby ulWbmPjtbJc73Mhr+HVlVjCrdHLP1m6Mg1id56KRad0SoNhasOrGkIqMTZBI8omkFtoz DojA== X-Forwarded-Encrypted: i=1; AJvYcCX00joxlOzbrVwFMCKC0cOMaQHZpudM5DMjqw3gXelJil5B07AyPYurqsDG50eYlESj1rm8ESxnXeif/U4=@vger.kernel.org X-Gm-Message-State: AOJu0Yy7fv8FezKOR5aNG3NrDuPS4uVWZvdP9/V3RkdApjAQs2CmWigk t6M6RcaLJZ9gPjRZES/o3VmHlMpdggbycrntkOXmTLtkQGVJ75++7MILO5QumMB3 X-Gm-Gg: ATEYQzz1332FAAsGV3cC0Z8P8+jSMFSV24rqQjKL1zHlJ5lJdvhxxG5NL16aQogjE/Y RGUo0AHhNJ1ZsNz+kXC7WKf7vkzQ5gP+yz9z3d4ERmo1Tl6EwRocqsZOGL6IKNwQEktvBR0apKm worY3rvl3T0O/Z1pBTfiZ1uCBOP95jwnJPlmbHgDnJhFnFn4he1GQQOTt8I3gXtKKiqRV2DUQP8 nEvAJNy26EtRidtriLM0WBlEFpchnKRrgjpZG8gTPc12CXZ4/6osvVaoCuGJFaotC2ibrkjF/3U g2ZiUhJp+XbQQmONm2RwHFabCpAPB/0E78wWUpgZpvF3tROyMiI3eUfQlqs9wpjC/fsrhweq4yp t2HzCmts6aPYyNV0h4qgwMsjv09jwbDX7Mbs5reiTlxd/SaZr8I2s2FmMCG9wIKcrPokVB3Eg7Q 3eJeHgygfRWN8FkEF6ZbQe/jZhV/P4MjjALBXOHSOo0TsZUmAVLKZweqxXWyhQdGQpQdelaRKId m0qlofzYJL98qUr3sApTXdeSo+ZB5kgquxg1J0aiGRaBcWIN7IigQ== X-Received: by 2002:a17:90b:3f8f:b0:359:f8c3:dada with SMTP id 98e67ed59e1d1-359f8c3e121mr363546a91.13.1773128813962; Tue, 10 Mar 2026 00:46:53 -0700 (PDT) Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([209.132.188.88]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-359bc7ef38csm7260607a91.2.2026.03.10.00.46.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2026 00:46:53 -0700 (PDT) From: Hangbin Liu Date: Tue, 10 Mar 2026 15:45:05 +0800 Subject: [PATCH net-next 1/3] net: use ndo_set_features to set offload features for bonding/bridge/team Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260310-offload_compute-v1-1-3df79c09ea65@gmail.com> References: <20260310-offload_compute-v1-0-3df79c09ea65@gmail.com> In-Reply-To: <20260310-offload_compute-v1-0-3df79c09ea65@gmail.com> To: Jay Vosburgh , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Jiri Pirko , Nikolay Aleksandrov , Ido Schimmel , Simon Horman , Sridhar Samudrala Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bridge@lists.linux.dev, Hangbin Liu X-Mailer: b4 0.14.3 Convert bonding, bridge, and team drivers to use ndo_set_features callback instead of manually calling netdev_compute_master_upper_features() during port add/remove operations. This change centralizes the feature computation flow: Before: - netdev_master_upper_dev_link() - netdev_compute_master_upper_features() <- called manually - compute offload features - netdev_change_features() - __netdev_update_features() - update other features After: - netdev_master_upper_dev_link() - __netdev_upper_dev_link() - netdev_change_features() - __netdev_update_features() - ndo_set_features() - netdev_compute_master_upper_features() This ensures offload features are computed automatically when upper/lower device links change, removing the need for manual feature computation calls in the driver code. The netdev_change_features() call in team_uninit() is also removed since it calls team_port_del() for each port, which now triggers feature updates automatically. Signed-off-by: Hangbin Liu --- drivers/net/bonding/bond_main.c | 11 ++++++++--- drivers/net/team/team_core.c | 12 ++++++++---- net/bridge/br_device.c | 7 +++++++ net/bridge/br_if.c | 4 ---- net/core/dev.c | 8 ++++++-- 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_mai= n.c index 0ccf928eecde..4d32b06079ee 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1509,6 +1509,12 @@ static netdev_features_t bond_fix_features(struct ne= t_device *dev, return features; } =20 +static int bond_set_features(struct net_device *dev, netdev_features_t fea= tures) +{ + netdev_compute_master_upper_features(dev, true); + return 0; +} + static void bond_setup_by_slave(struct net_device *bond_dev, struct net_device *slave_dev) { @@ -2228,7 +2234,6 @@ int bond_enslave(struct net_device *bond_dev, struct = net_device *slave_dev, } =20 bond->slave_cnt++; - netdev_compute_master_upper_features(bond->dev, true); bond_set_carrier(bond); =20 /* Needs to be called before bond_select_active_slave(), which will @@ -2483,7 +2488,6 @@ static int __bond_release_one(struct net_device *bond= _dev, call_netdevice_notifiers(NETDEV_RELEASE, bond->dev); } =20 - netdev_compute_master_upper_features(bond->dev, true); if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) && (old_features & NETIF_F_VLAN_CHALLENGED)) slave_info(bond_dev, slave_dev, "last VLAN challenged slave left bond - = VLAN blocking is removed\n"); @@ -3975,7 +3979,7 @@ static int bond_slave_netdev_event(unsigned long even= t, case NETDEV_FEAT_CHANGE: if (!bond->notifier_ctx) { bond->notifier_ctx =3D true; - netdev_compute_master_upper_features(bond->dev, true); + netdev_change_features(bond->dev); bond->notifier_ctx =3D false; } break; @@ -5897,6 +5901,7 @@ static const struct net_device_ops bond_netdev_ops = =3D { .ndo_add_slave =3D bond_enslave, .ndo_del_slave =3D bond_release, .ndo_fix_features =3D bond_fix_features, + .ndo_set_features =3D bond_set_features, .ndo_features_check =3D passthru_features_check, .ndo_get_xmit_slave =3D bond_xmit_get_slave, .ndo_sk_get_lower_dev =3D bond_sk_get_lower_dev, diff --git a/drivers/net/team/team_core.c b/drivers/net/team/team_core.c index b7282f5c9632..4906ea3717b1 100644 --- a/drivers/net/team/team_core.c +++ b/drivers/net/team/team_core.c @@ -1247,7 +1247,6 @@ static int team_port_add(struct team *team, struct ne= t_device *port_dev, port->index =3D -1; list_add_tail_rcu(&port->list, &team->port_list); team_port_enable(team, port); - netdev_compute_master_upper_features(team->dev, true); __team_port_change_port_added(port, !!netif_oper_up(port_dev)); __team_options_change_check(team); =20 @@ -1337,7 +1336,6 @@ static int team_port_del(struct team *team, struct ne= t_device *port_dev, bool un } kfree_rcu(port, rcu); netdev_info(dev, "Port device %s removed\n", portname); - netdev_compute_master_upper_features(team->dev, true); =20 return 0; } @@ -1645,7 +1643,6 @@ static void team_uninit(struct net_device *dev) team_mcast_rejoin_fini(team); team_notify_peers_fini(team); team_queue_override_fini(team); - netdev_change_features(dev); } =20 static void team_destructor(struct net_device *dev) @@ -1972,6 +1969,12 @@ static netdev_features_t team_fix_features(struct ne= t_device *dev, return features; } =20 +static int team_set_features(struct net_device *dev, netdev_features_t fea= tures) +{ + netdev_compute_master_upper_features(dev, true); + return 0; +} + static int team_change_carrier(struct net_device *dev, bool new_carrier) { struct team *team =3D netdev_priv(dev); @@ -2007,6 +2010,7 @@ static const struct net_device_ops team_netdev_ops = =3D { .ndo_add_slave =3D team_add_slave, .ndo_del_slave =3D team_del_slave, .ndo_fix_features =3D team_fix_features, + .ndo_set_features =3D team_set_features, .ndo_change_carrier =3D team_change_carrier, .ndo_features_check =3D passthru_features_check, }; @@ -2944,7 +2948,7 @@ static int team_device_event(struct notifier_block *u= nused, case NETDEV_FEAT_CHANGE: if (!port->team->notifier_ctx) { port->team->notifier_ctx =3D true; - netdev_compute_master_upper_features(port->team->dev, true); + netdev_change_features(port->team->dev); port->team->notifier_ctx =3D false; } break; diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index f7502e62dd35..f82082050e36 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -289,6 +289,12 @@ static netdev_features_t br_fix_features(struct net_de= vice *dev, return br_features_recompute(br, features); } =20 +static int br_set_features(struct net_device *dev, netdev_features_t featu= res) +{ + netdev_compute_master_upper_features(dev, false); + return 0; +} + #ifdef CONFIG_NET_POLL_CONTROLLER static void br_poll_controller(struct net_device *br_dev) { @@ -456,6 +462,7 @@ static const struct net_device_ops br_netdev_ops =3D { .ndo_add_slave =3D br_add_slave, .ndo_del_slave =3D br_del_slave, .ndo_fix_features =3D br_fix_features, + .ndo_set_features =3D br_set_features, .ndo_fdb_add =3D br_fdb_add, .ndo_fdb_del =3D br_fdb_delete, .ndo_fdb_del_bulk =3D br_fdb_delete_bulk, diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index d39571e13744..030248bc94c5 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -680,8 +680,6 @@ int br_add_if(struct net_bridge *br, struct net_device = *dev, =20 br_mtu_auto_adjust(br); =20 - netdev_compute_master_upper_features(br->dev, false); - kobject_uevent(&p->kobj, KOBJ_ADD); =20 return 0; @@ -734,8 +732,6 @@ int br_del_if(struct net_bridge *br, struct net_device = *dev) if (changed_addr) call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); =20 - netdev_compute_master_upper_features(br->dev, false); - return 0; } =20 diff --git a/net/core/dev.c b/net/core/dev.c index 6fc9350f0be8..ce1d9c73e6ce 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -8919,6 +8919,9 @@ static int __netdev_upper_dev_link(struct net_device = *dev, __netdev_walk_all_upper_dev(upper_dev, __netdev_update_lower_level, priv); =20 + /* re-compute all features after adding link */ + netdev_change_features(upper_dev); + return 0; =20 rollback: @@ -9011,6 +9014,9 @@ static void __netdev_upper_dev_unlink(struct net_devi= ce *dev, __netdev_update_lower_level(upper_dev, priv); __netdev_walk_all_upper_dev(upper_dev, __netdev_update_lower_level, priv); + + /* re-compute all features after removing link */ + netdev_change_features(upper_dev); } =20 /** @@ -12873,8 +12879,6 @@ void netdev_compute_master_upper_features(struct ne= t_device *dev, bool update_he =20 netif_set_tso_max_segs(dev, tso_max_segs); netif_set_tso_max_size(dev, tso_max_size); - - netdev_change_features(dev); } EXPORT_SYMBOL(netdev_compute_master_upper_features); =20 --=20 Git-155) From nobody Thu Apr 9 07:15:26 2026 Received: from mail-pj1-f53.google.com (mail-pj1-f53.google.com [209.85.216.53]) (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 A5FBC363C50 for ; Tue, 10 Mar 2026 07:47:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773128823; cv=none; b=g/zFOrnMxtWgsIdpBJPLcXGKJLAbiGjunj8EHBQKDgYd1rxjreoja/4emuMzI93tw971siZx24XYybGNaHT7ldkt1x2QhjeMZn5xQmqVZ1c14pE9bn51aZa1xd7SBKm8Qmfd59bVfkd94Mt2yzzERFvBeFYLBaFyHOipO1k7xiE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773128823; c=relaxed/simple; bh=ckIN5ASkuNOY9pUfpsVNZbSyJ16scvuiSr26ig8bsBM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RwndYQZlu4NmHUCtO1iIJ3Gs/vMTIOU9Q0KW+xVNOFZECzdclXoDFEWNGbg9f6IFiMkqqiVPH2EHaPsLuVzV8fzSQGwARIr/moO2tm5bEjOEiYDK2PvHKRJPOOaEWPki1Tl3KSmIBq9uyDpHz5ipKyKP7wwJ9yVlQFF2k4JmS9s= 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=P+RGhi4f; arc=none smtp.client-ip=209.85.216.53 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="P+RGhi4f" Received: by mail-pj1-f53.google.com with SMTP id 98e67ed59e1d1-35983877dc5so4109014a91.2 for ; Tue, 10 Mar 2026 00:47:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773128820; x=1773733620; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=djyy+9DJ7NGUH5/yQnciZZwbkw5XEWCb6BieiKG0OKc=; b=P+RGhi4fJv0WuGJifLYhB3BxBwXFLt5xBL5YYWH6dBHzWt+sixle3rMvsmTVptqP0C no+jzpzltm6GldEddudb84pYSUqs+4AlhWgZ18t5QD07ALcUbmeYCQS7wMsSSYtxGIEt zxFJ17TFlJ4lj8850XF+E2D9B4l0RLcJYHddcMRuisajbFMfY+J7k/Np1oxUYLEoeI18 roTcNXkDSwIx0SPC1hgcUZr3TF9W9wzJvp0lTKmNlH7e5QYKuAP7ItfUQT2lVjLVEhQV ZS1gj0W/nS1cn/kMvXMh40ewEP4OGvs/Up3MLkHbTQsu3LzsrwhWGsMhiIgRHHgSHQwH lKDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773128820; x=1773733620; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=djyy+9DJ7NGUH5/yQnciZZwbkw5XEWCb6BieiKG0OKc=; b=I+fTWPBWik+9vPQJqwRlzG3uSu5QeXtfwuELMHQuwZugyzzCuZkgdfEaCyvwqOm8j4 aE01mKRHDo6zSZc3RwDItsiSSrxNOKw1SQP4cfdKX//kR1O8eXz8F5f3JovdRojMgqk/ vBTmrxNRmJaImAcQVCp3wwS8Zmzbqt86gsZLDKd4bLF4HjEEjF6AmL6Orq4MfEKtFGW9 zjm2h8X7HtbrHGw/oJK533UL/1P7mmx4OA8NBg37P2iOx6ekmKq6i/mio8IgsFiFtz2V 21I/Svaf4Q8BiK5UEVRwZ4ODSAgV6Nq4jtT+/fzAQWwdMAQ5fGfYmYYSVVAfmRbOwjK2 Ep8g== X-Forwarded-Encrypted: i=1; AJvYcCUIyRrRL1YrKm93CCaOaQ2EsJMGs6LYRYI5q8tyIHlb6lnI+yliY+OIPXKz3KJ4YrL1VL33DVvnWYObM7k=@vger.kernel.org X-Gm-Message-State: AOJu0Yzpf8O0mxp8lnI/g53tVmf4o/JFimIRmypBQT4gbydZ4gn7QAAD J1UnZ/wdvfbkLBTelNPRCFzKmLA3dYtekk5uqiOuohfTXUd7hNXKMigNghpbP7iK X-Gm-Gg: ATEYQzxXLBAzD5bhAhQLcj/qrRusrDH/rWSFhJAkFYX7Ja0If+ZEM5N6RfJafg+wrWt iDg7tr+0vJ01phW76bNKrSbP5cVPjBKSvZAuq6vQd6p0QCBgXIh39x7C58SvhhDeYH3p34jKIWM W/cKyFlWbdZFZi8ep6U+AtyR7EIao54QZFfIehCtwGMfTf4bf08P/tFQbvuptt2JbJ99rlnCBR7 Ix8TZhxCHo5EXbTsKkaueReUt8XpB5PD/V8LWu2h9MKMaaqNLXaNizPVGMk9D0qIjtRGp9PcKhr KlUpnwYfRe9k12n8Stm60sdVf7XTvU3d6P4w8Q7PV8EToVohceNx5TmmBlBkGuVX70Ti8D1A1CC qZsXlQ4WCMjQrS5Pn3DRD+5k2ctb8Cinfm0VXBNRF4ckq/e8QuP36G7Kon8QcbDNWwM88jgY+o3 b0Akv77KEMgSNHT8G+5oZSlPfmLMEjcDUXzYjrKJ3ra6N6Op103vnrDmyk2q/NrehLPvqlh4q/f yjZgTWcFiJvS0E12ok3A8/ku9UmLAGkoIuS7efVNkk= X-Received: by 2002:a17:90b:3a4b:b0:359:7fe6:7e5 with SMTP id 98e67ed59e1d1-359be30aee2mr10825721a91.24.1773128819911; Tue, 10 Mar 2026 00:46:59 -0700 (PDT) Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([209.132.188.88]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-359bc7ef38csm7260607a91.2.2026.03.10.00.46.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2026 00:46:59 -0700 (PDT) From: Hangbin Liu Date: Tue, 10 Mar 2026 15:45:06 +0800 Subject: [PATCH net-next 2/3] failover: use ndo_set_features for failover offload compute Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260310-offload_compute-v1-2-3df79c09ea65@gmail.com> References: <20260310-offload_compute-v1-0-3df79c09ea65@gmail.com> In-Reply-To: <20260310-offload_compute-v1-0-3df79c09ea65@gmail.com> To: Jay Vosburgh , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Jiri Pirko , Nikolay Aleksandrov , Ido Schimmel , Simon Horman , Sridhar Samudrala Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bridge@lists.linux.dev, Hangbin Liu X-Mailer: b4 0.14.3 Convert net_failover to use the ndo_set_features callback and calls netdev_compute_master_upper_features() to compute new offload flags during slave registration/unregistration. This simplifies the failover code significantly by removing the custom feature computation logic and relying on the centralized feature update mechanism. The callback is automatically invoked during feature updates when upper/lower device links change. Signed-off-by: Hangbin Liu --- drivers/net/net_failover.c | 67 ++++++------------------------------------= ---- include/net/net_failover.h | 7 ----- 2 files changed, 8 insertions(+), 66 deletions(-) diff --git a/drivers/net/net_failover.c b/drivers/net/net_failover.c index d0361aaf25ef..10041a271bf5 100644 --- a/drivers/net/net_failover.c +++ b/drivers/net/net_failover.c @@ -300,6 +300,12 @@ static int net_failover_vlan_rx_kill_vid(struct net_de= vice *dev, __be16 proto, return 0; } =20 +static int net_failover_set_features(struct net_device *dev, netdev_featur= es_t features) +{ + netdev_compute_master_upper_features(dev, true); + return 0; +} + static const struct net_device_ops failover_dev_ops =3D { .ndo_open =3D net_failover_open, .ndo_stop =3D net_failover_close, @@ -312,6 +318,7 @@ static const struct net_device_ops failover_dev_ops =3D= { .ndo_vlan_rx_kill_vid =3D net_failover_vlan_rx_kill_vid, .ndo_validate_addr =3D eth_validate_addr, .ndo_features_check =3D passthru_features_check, + .ndo_set_features =3D net_failover_set_features, }; =20 #define FAILOVER_NAME "net_failover" @@ -373,61 +380,6 @@ static rx_handler_result_t net_failover_handle_frame(s= truct sk_buff **pskb) return RX_HANDLER_ANOTHER; } =20 -static void net_failover_compute_features(struct net_device *dev) -{ - netdev_features_t vlan_features =3D FAILOVER_VLAN_FEATURES & - NETIF_F_ALL_FOR_ALL; - netdev_features_t enc_features =3D FAILOVER_ENC_FEATURES; - unsigned short max_hard_header_len =3D ETH_HLEN; - unsigned int dst_release_flag =3D IFF_XMIT_DST_RELEASE | - IFF_XMIT_DST_RELEASE_PERM; - struct net_failover_info *nfo_info =3D netdev_priv(dev); - struct net_device *primary_dev, *standby_dev; - - primary_dev =3D rcu_dereference(nfo_info->primary_dev); - if (primary_dev) { - vlan_features =3D - netdev_increment_features(vlan_features, - primary_dev->vlan_features, - FAILOVER_VLAN_FEATURES); - enc_features =3D - netdev_increment_features(enc_features, - primary_dev->hw_enc_features, - FAILOVER_ENC_FEATURES); - - dst_release_flag &=3D primary_dev->priv_flags; - if (primary_dev->hard_header_len > max_hard_header_len) - max_hard_header_len =3D primary_dev->hard_header_len; - } - - standby_dev =3D rcu_dereference(nfo_info->standby_dev); - if (standby_dev) { - vlan_features =3D - netdev_increment_features(vlan_features, - standby_dev->vlan_features, - FAILOVER_VLAN_FEATURES); - enc_features =3D - netdev_increment_features(enc_features, - standby_dev->hw_enc_features, - FAILOVER_ENC_FEATURES); - - dst_release_flag &=3D standby_dev->priv_flags; - if (standby_dev->hard_header_len > max_hard_header_len) - max_hard_header_len =3D standby_dev->hard_header_len; - } - - dev->vlan_features =3D vlan_features; - dev->hw_enc_features =3D enc_features | NETIF_F_GSO_ENCAP_ALL; - dev->hard_header_len =3D max_hard_header_len; - - dev->priv_flags &=3D ~IFF_XMIT_DST_RELEASE; - if (dst_release_flag =3D=3D (IFF_XMIT_DST_RELEASE | - IFF_XMIT_DST_RELEASE_PERM)) - dev->priv_flags |=3D IFF_XMIT_DST_RELEASE; - - netdev_change_features(dev); -} - static void net_failover_lower_state_changed(struct net_device *slave_dev, struct net_device *primary_dev, struct net_device *standby_dev) @@ -550,7 +502,6 @@ static int net_failover_slave_register(struct net_devic= e *slave_dev, } =20 net_failover_lower_state_changed(slave_dev, primary_dev, standby_dev); - net_failover_compute_features(failover_dev); =20 call_netdevice_notifiers(NETDEV_JOIN, slave_dev); =20 @@ -621,8 +572,6 @@ static int net_failover_slave_unregister(struct net_dev= ice *slave_dev, =20 dev_put(slave_dev); =20 - net_failover_compute_features(failover_dev); - netdev_info(failover_dev, "failover %s slave:%s unregistered\n", slave_is_standby ? "standby" : "primary", slave_dev->name); =20 @@ -736,7 +685,7 @@ struct failover *net_failover_create(struct net_device = *standby_dev) /* Don't allow failover devices to change network namespaces. */ failover_dev->netns_immutable =3D true; =20 - failover_dev->hw_features =3D FAILOVER_VLAN_FEATURES | + failover_dev->hw_features =3D MASTER_UPPER_DEV_VLAN_FEATURES | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER; diff --git a/include/net/net_failover.h b/include/net/net_failover.h index b12a1c469d1c..f0f038d113a0 100644 --- a/include/net/net_failover.h +++ b/include/net/net_failover.h @@ -30,11 +30,4 @@ struct net_failover_info { struct failover *net_failover_create(struct net_device *standby_dev); void net_failover_destroy(struct failover *failover); =20 -#define FAILOVER_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ - NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \ - NETIF_F_HIGHDMA | NETIF_F_LRO) - -#define FAILOVER_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ - NETIF_F_RXCSUM | NETIF_F_ALL_TSO) - #endif /* _NET_FAILOVER_H */ --=20 Git-155) From nobody Thu Apr 9 07:15:26 2026 Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) (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 D0C52363C50 for ; Tue, 10 Mar 2026 07:47:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773128828; cv=none; b=JkVAWshNdDOd8JYXWDzPblxT/aEzyGjyRWxhjIn+wa34GT/hRBhg1vBS4o+5KIGtQfbaWjImBYtjfbXUep7pKhC+q0f51kVOfx0AnxVmlodnCGh+1xC1RzfzR2BTqFkPzonm5qHcSNcC/srXsV8lkH/MO8jzkSzHxLnZv3Jc8hM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773128828; c=relaxed/simple; bh=bXnDNSFidNz36SeGMTKr9aEsO9Td+iPTz2QUPB6xp3c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ed3OHTWTrrFWnuX1luCunFXup8WF/P/XkdiATzGMy9p1EpyYnjgM/RZH7nApxjv0IVec2Hrwg0JYtQ2lIGg/v7IJEyHaOi1f3qTJc2fY4rz3MqmeZgEVRJQLUVp0+Jki8h1XczWE20N8UV04LicqZUAeT0yjABjT7415S8bSVss= 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=Gow9+562; arc=none smtp.client-ip=209.85.216.41 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="Gow9+562" Received: by mail-pj1-f41.google.com with SMTP id 98e67ed59e1d1-3590042fa8eso7934640a91.1 for ; Tue, 10 Mar 2026 00:47:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773128826; x=1773733626; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=3MrEEXv7Xy2jJrXRIKwxLssaRaTIm50HmDgCOhNMffI=; b=Gow9+562BFRpy9U2GY8TssgH+Gaw7cOuYfzpcHt/I9pTfBraDfXUoMpUslObZ9eBQG YUGImjaSUqlb9txAuu/rxdFyx5Kl4B+xQLu6gr9T6oMvmiw5dS2HULs3moEFFbASS6aT /CBAEwLpm/3xJsJZRGwT4zIdAGPo4+Mreu0zucrYPQszeGNQHm3Gdt9y6MfDNTToR6KE oKLqlF3kuP8zYPf99UQE70vYW15bpnWp6ODajaOg1ma+MEGtjXUfGTAzU5TnuCMd6Cmd XKCNBIun0VDfKe8rTVNNMFPa1yxSOBES4x7JwuRHRiBbbwCZ4voHn2rpFy2UUd+A8FTp GV3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773128826; x=1773733626; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=3MrEEXv7Xy2jJrXRIKwxLssaRaTIm50HmDgCOhNMffI=; b=COvO2ieGSw9DB0RrG7vYTdkdNwMi9w9FlOyM9ASw97fW3ElWeIHXchiYZBCaZ0y3w+ Y8cyxMWSvSE/tvPil9zmAmk5TkOp6UlSKIXG8Wd0fOalaDyUgGNzJLOoITYEy6ZHoBCT w6fk7T+lKpUhw2aCD9hD+H+YBzMND7nJ4SHKeJypmlExFW1RRVynpAKwgpOjSmEGwB6B bFL9FD6au5+iE7WDdnA9r/bMY6QKjOwiYGlSA3fyyBkypWhy7TeZtfeyD47a4QLfCHqW fuIgKpvXur9zVBs76Tkv9zwdzj5DBIba3il2XRZt+X47aPNO2KBMAZ6LRhu13El37Is5 KzCg== X-Forwarded-Encrypted: i=1; AJvYcCUoetRDmcLsa0U5VaxCltcA+qb200nM7T4PN+9eVHz3CB5n/Pwgu0lHiGUwA0mk56uT8CRo4E1r0hcG+HM=@vger.kernel.org X-Gm-Message-State: AOJu0YxeihtMtHFIKypsEkmzjrli9eIrG9KRoJYEVWITYt/ZgPO4/Im6 qCTUkyorwU0dKBXm+t74oYq7LxFUjiGOOhSWsp+rn/rkxDqpqx6RjMY2UVtCEVpB X-Gm-Gg: ATEYQzy7TzGxUlTYO0rHvdTwk8v46DzJSBjWqDUeiRVq+FrRNa+xoHqq5cd+gp9KwNk vl7JJMm+/oP1SReE0jGx9ywl2IWyjKMeHB35b95IwMw7JJtA5E88GF2VuxEjSPZBUHHOPZ83kJp TjrfeiIY8DFICRIEsPe9QXCOSjz9qiRs70QZRQ/gGr31USd2S7O9bSqpevaXYqHLsHm5ebAGLYY SjIlviTzSArl/JOFENS33KlpDSSuhdVXg2Ud6eXu8VH//NJJO2K+tUKuKFdRLFg7n389BAFmuoK jXNStRugzirO4LAtRhOV0LcFIkkrkBa0v38IfDduTssWRsl7cw8ZqhPAA+47ZHX+TvOyUAqUix4 Sd1oa/HzT6ygy/1FVici5XnqOuNjcYNMh8P30jqXwtln46a03kL9Lv4wSX0JUJfF1QIjfHV2IFm aLFlHyGh/bbvv/MFN25rRF3nMsZnoMLqh0KErg0AG094NziivqokU0j/RxvQcyeYOHHW1Ye3wQA mfvfoReCRf8LaMZvhOIpk5tCFJLvY43HWzi2mS+sAI= X-Received: by 2002:a17:90b:5252:b0:359:9bad:13d9 with SMTP id 98e67ed59e1d1-359be29eea6mr12832642a91.15.1773128826073; Tue, 10 Mar 2026 00:47:06 -0700 (PDT) Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([209.132.188.88]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-359bc7ef38csm7260607a91.2.2026.03.10.00.47.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2026 00:47:05 -0700 (PDT) From: Hangbin Liu Date: Tue, 10 Mar 2026 15:45:07 +0800 Subject: [PATCH net-next 3/3] net: no need to disable LRO specifically Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260310-offload_compute-v1-3-3df79c09ea65@gmail.com> References: <20260310-offload_compute-v1-0-3df79c09ea65@gmail.com> In-Reply-To: <20260310-offload_compute-v1-0-3df79c09ea65@gmail.com> To: Jay Vosburgh , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Jiri Pirko , Nikolay Aleksandrov , Ido Schimmel , Simon Horman , Sridhar Samudrala Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bridge@lists.linux.dev, Hangbin Liu X-Mailer: b4 0.14.3 In commit "net: use ndo_set_features to set offload features for bonding/bridge/team" we called netdev_change_features() in __netdev_upper_dev_link(), which will disable LRO automatically on lower device if upper device doesn't have LRO enabled. So we don't need to dev_disable_lro() again after netdev_upper_dev_link(). Signed-off-by: Hangbin Liu --- drivers/net/bonding/bond_main.c | 3 --- drivers/net/team/team_core.c | 3 --- net/8021q/vlan.c | 2 -- net/bridge/br_if.c | 2 -- net/hsr/hsr_slave.c | 1 - 5 files changed, 11 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_mai= n.c index 4d32b06079ee..5b117acb1138 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2177,9 +2177,6 @@ int bond_enslave(struct net_device *bond_dev, struct = net_device *slave_dev, } #endif =20 - if (!(bond_dev->features & NETIF_F_LRO)) - dev_disable_lro(slave_dev); - res =3D netdev_rx_handler_register(slave_dev, bond_handle_frame, new_slave); if (res) { diff --git a/drivers/net/team/team_core.c b/drivers/net/team/team_core.c index 4906ea3717b1..73d4f68a7ccd 100644 --- a/drivers/net/team/team_core.c +++ b/drivers/net/team/team_core.c @@ -1191,9 +1191,6 @@ static int team_port_add(struct team *team, struct ne= t_device *port_dev, goto err_enable_netpoll; } =20 - if (!(dev->features & NETIF_F_LRO)) - dev_disable_lro(port_dev); - err =3D netdev_rx_handler_register(port_dev, team_handle_frame, port); if (err) { diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 2b74ed56eb16..fda3a80e9340 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -193,8 +193,6 @@ int register_vlan_dev(struct net_device *dev, struct ne= tlink_ext_ack *extack) vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, dev); grp->nr_vlan_devs++; =20 - netdev_update_features(dev); - return 0; =20 out_unregister_netdev: diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 030248bc94c5..0aa653a1e651 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -620,8 +620,6 @@ int br_add_if(struct net_bridge *br, struct net_device = *dev, if (err) goto err5; =20 - dev_disable_lro(dev); - list_add_rcu(&p->list, &br->port_list); =20 nbp_update_port_count(br); diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c index 44f83c8c56a7..4b6ab185392b 100644 --- a/net/hsr/hsr_slave.c +++ b/net/hsr/hsr_slave.c @@ -169,7 +169,6 @@ static int hsr_portdev_setup(struct hsr_priv *hsr, stru= ct net_device *dev, res =3D netdev_rx_handler_register(dev, hsr_handle_frame, port); if (res) goto fail_rx_handler; - dev_disable_lro(dev); =20 return 0; =20 --=20 Git-155)