[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240620114711.777046-5-edumazet@google.com>
Date: Thu, 20 Jun 2024 11:47:09 +0000
From: Eric Dumazet <edumazet@...gle.com>
To: "David S . Miller" <davem@...emloft.net>, Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>
Cc: Ziwei Xiao <ziweixiao@...gle.com>, Praveen Kaligineedi <pkaligineedi@...gle.com>,
Harshitha Ramamurthy <hramamurthy@...gle.com>, Willem de Bruijn <willemb@...gle.com>,
Jeroen de Borst <jeroendb@...gle.com>, Shailend Chand <shailend@...gle.com>, netdev@...r.kernel.org,
eric.dumazet@...il.com, Eric Dumazet <edumazet@...gle.com>
Subject: [PATCH net-next 4/6] net: ethtool: call ethtool_get_one_feature()
without RTNL
ethtool_get_one_feature() is used by ETHTOOL_GTXCSUM, ETHTOOL_GRXCSUM,
ETHTOOL_GSG, ETHTOOL_GTSO, ETHTOOL_GGSO and ETHTOOL_GGRO.
Add WRITE_ONCE() and READ_ONCE() annotations on dev->features.
Note that many READ_ONCE() annotations are probably missing in many drivers,
but this is orthogonal to this patch.
Signed-off-by: Eric Dumazet <edumazet@...gle.com>
---
net/core/dev.c | 10 +++++-----
net/ethtool/ioctl.c | 30 ++++++++++++++++--------------
2 files changed, 21 insertions(+), 19 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 093d82bf0e2886d4948f4952353c71c92e3586c6..b18223ed269f24bedd02b7c435de0ce2f1f8edf3 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3536,7 +3536,7 @@ static netdev_features_t gso_features_check(const struct sk_buff *skb,
netdev_features_t netif_skb_features(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
- netdev_features_t features = dev->features;
+ netdev_features_t features = READ_ONCE(dev->features);
if (skb_is_gso(skb))
features = gso_features_check(skb, dev, features);
@@ -10016,7 +10016,7 @@ int __netdev_update_features(struct net_device *dev)
* but *after* calling udp_tunnel_drop_rx_info.
*/
if (features & NETIF_F_RX_UDP_TUNNEL_PORT) {
- dev->features = features;
+ WRITE_ONCE(dev->features, features);
udp_tunnel_get_rx_info(dev);
} else {
udp_tunnel_drop_rx_info(dev);
@@ -10025,7 +10025,7 @@ int __netdev_update_features(struct net_device *dev)
if (diff & NETIF_F_HW_VLAN_CTAG_FILTER) {
if (features & NETIF_F_HW_VLAN_CTAG_FILTER) {
- dev->features = features;
+ WRITE_ONCE(dev->features, features);
err |= vlan_get_rx_ctag_filter_info(dev);
} else {
vlan_drop_rx_ctag_filter_info(dev);
@@ -10034,14 +10034,14 @@ int __netdev_update_features(struct net_device *dev)
if (diff & NETIF_F_HW_VLAN_STAG_FILTER) {
if (features & NETIF_F_HW_VLAN_STAG_FILTER) {
- dev->features = features;
+ WRITE_ONCE(dev->features, features);
err |= vlan_get_rx_stag_filter_info(dev);
} else {
vlan_drop_rx_stag_filter_info(dev);
}
}
- dev->features = features;
+ WRITE_ONCE(dev->features, features);
}
return err < 0 ? 0 : 1;
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 70bb0d2fa2ed416fdff3de71a4f752e4a1bba67a..d0c9d2ad9c3d0acb1be00eb4970d3a1ef9da030a 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -245,13 +245,13 @@ static netdev_features_t ethtool_get_feature_mask(u32 eth_cmd)
}
}
-static int ethtool_get_one_feature(struct net_device *dev,
+static int ethtool_get_one_feature(const struct net_device *dev,
char __user *useraddr, u32 ethcmd)
{
netdev_features_t mask = ethtool_get_feature_mask(ethcmd);
struct ethtool_value edata = {
.cmd = ethcmd,
- .data = !!(dev->features & mask),
+ .data = !!(READ_ONCE(dev->features) & mask),
};
if (copy_to_user(useraddr, &edata, sizeof(edata)))
@@ -3049,14 +3049,6 @@ __dev_ethtool(struct net_device *dev, struct ifreq *ifr,
case ETHTOOL_SFEATURES:
rc = ethtool_set_features(dev, useraddr);
break;
- case ETHTOOL_GTXCSUM:
- case ETHTOOL_GRXCSUM:
- case ETHTOOL_GSG:
- case ETHTOOL_GTSO:
- case ETHTOOL_GGSO:
- case ETHTOOL_GGRO:
- rc = ethtool_get_one_feature(dev, useraddr, ethcmd);
- break;
case ETHTOOL_STXCSUM:
case ETHTOOL_SRXCSUM:
case ETHTOOL_SSG:
@@ -3178,10 +3170,20 @@ int dev_ethtool(struct net *net, struct ifreq *ifr, void __user *useraddr)
if (!netif_device_present(dev))
goto out_pm;
- rtnl_lock();
- rc = __dev_ethtool(dev, ifr, useraddr, ethcmd, sub_cmd, state);
- rtnl_unlock();
-
+ switch (ethcmd) {
+ case ETHTOOL_GTXCSUM:
+ case ETHTOOL_GRXCSUM:
+ case ETHTOOL_GSG:
+ case ETHTOOL_GTSO:
+ case ETHTOOL_GGSO:
+ case ETHTOOL_GGRO:
+ rc = ethtool_get_one_feature(dev, useraddr, ethcmd);
+ break;
+ default:
+ rtnl_lock();
+ rc = __dev_ethtool(dev, ifr, useraddr, ethcmd, sub_cmd, state);
+ rtnl_unlock();
+ }
out_pm:
if (dev->dev.parent)
pm_runtime_put(dev->dev.parent);
--
2.45.2.627.g7a2c4fd464-goog
Powered by blists - more mailing lists