* [PATCH net-next] net: convert dev->rtnl_link_state to a bool
@ 2025-04-10 1:42 Jakub Kicinski
2025-04-10 15:45 ` Stanislav Fomichev
0 siblings, 1 reply; 2+ messages in thread
From: Jakub Kicinski @ 2025-04-10 1:42 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, Jakub Kicinski,
sdf, kuniyu
netdevice reg_state was split into two 16 bit enums back in 2010
in commit a2835763e130 ("rtnetlink: handle rtnl_link netlink
notifications manually"). Since the split the fields have been
moved apart, and last year we converted reg_state to a normal
u8 in commit 4d42b37def70 ("net: convert dev->reg_state to u8").
rtnl_link_state being a 16 bitfield makes no sense. Convert it
to a single bool, it seems very unlikely after 15 years that
we'll need more values in it.
We could drop dev->rtnl_link_ops from the conditions but feels
like having it there more clearly points at the reason for this
hack.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
CC: sdf@fomichev.me
CC: kuniyu@amazon.com
---
.../networking/net_cachelines/net_device.rst | 2 +-
include/linux/netdevice.h | 10 ++--------
net/core/dev.c | 6 ++----
net/core/rtnetlink.c | 15 ++++++++-------
4 files changed, 13 insertions(+), 20 deletions(-)
diff --git a/Documentation/networking/net_cachelines/net_device.rst b/Documentation/networking/net_cachelines/net_device.rst
index 6327e689e8a8..ca8605eb82ff 100644
--- a/Documentation/networking/net_cachelines/net_device.rst
+++ b/Documentation/networking/net_cachelines/net_device.rst
@@ -131,7 +131,7 @@ struct ref_tracker_dir refcnt_tracker
struct list_head link_watch_list
enum:8 reg_state
bool dismantle
-enum:16 rtnl_link_state
+bool rtnl_link_initilizing
bool needs_free_netdev
void*priv_destructor struct net_device
struct netpoll_info* npinfo read_mostly napi_poll/napi_poll_lock
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index dece2ae396a1..d3478e27e350 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1946,9 +1946,6 @@ enum netdev_reg_state {
*
* @reg_state: Register/unregister state machine
* @dismantle: Device is going to be freed
- * @rtnl_link_state: This enum represents the phases of creating
- * a new link
- *
* @needs_free_netdev: Should unregister perform free_netdev?
* @priv_destructor: Called from unregister
* @npinfo: XXX: need comments on this one
@@ -2363,11 +2360,8 @@ struct net_device {
/** @moving_ns: device is changing netns, protected by @lock */
bool moving_ns;
-
- enum {
- RTNL_LINK_INITIALIZED,
- RTNL_LINK_INITIALIZING,
- } rtnl_link_state:16;
+ /** @rtnl_link_initializing: Device being created, suppress events */
+ bool rtnl_link_initializing;
bool needs_free_netdev;
void (*priv_destructor)(struct net_device *dev);
diff --git a/net/core/dev.c b/net/core/dev.c
index b52efa4cec56..bd23559bdd82 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -11119,8 +11119,7 @@ int register_netdevice(struct net_device *dev)
* Prevent userspace races by waiting until the network
* device is fully setup before sending notifications.
*/
- if (!dev->rtnl_link_ops ||
- dev->rtnl_link_state == RTNL_LINK_INITIALIZED)
+ if (!(dev->rtnl_link_ops && dev->rtnl_link_initializing))
rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U, GFP_KERNEL, 0, NULL);
out:
@@ -12034,8 +12033,7 @@ void unregister_netdevice_many_notify(struct list_head *head,
*/
call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
- if (!dev->rtnl_link_ops ||
- dev->rtnl_link_state == RTNL_LINK_INITIALIZED)
+ if (!(dev->rtnl_link_ops && dev->rtnl_link_initializing))
skb = rtmsg_ifinfo_build_skb(RTM_DELLINK, dev, ~0U, 0,
GFP_KERNEL, NULL, 0,
portid, nlh);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index c23852835050..572cacbb39bd 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -3580,7 +3580,7 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm,
u32 portid, const struct nlmsghdr *nlh)
{
- unsigned int old_flags;
+ unsigned int old_flags, changed;
int err;
old_flags = dev->flags;
@@ -3591,12 +3591,13 @@ int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm,
return err;
}
- if (dev->rtnl_link_state == RTNL_LINK_INITIALIZED) {
- __dev_notify_flags(dev, old_flags, (old_flags ^ dev->flags), portid, nlh);
- } else {
- dev->rtnl_link_state = RTNL_LINK_INITIALIZED;
- __dev_notify_flags(dev, old_flags, ~0U, portid, nlh);
+ changed = old_flags ^ dev->flags;
+ if (dev->rtnl_link_initializing) {
+ dev->rtnl_link_initializing = false;
+ changed = ~0U;
}
+
+ __dev_notify_flags(dev, old_flags, changed, portid, nlh);
return 0;
}
EXPORT_SYMBOL(rtnl_configure_link);
@@ -3654,7 +3655,7 @@ struct net_device *rtnl_create_link(struct net *net, const char *ifname,
dev_net_set(dev, net);
dev->rtnl_link_ops = ops;
- dev->rtnl_link_state = RTNL_LINK_INITIALIZING;
+ dev->rtnl_link_initializing = true;
if (tb[IFLA_MTU]) {
u32 mtu = nla_get_u32(tb[IFLA_MTU]);
--
2.49.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH net-next] net: convert dev->rtnl_link_state to a bool
2025-04-10 1:42 [PATCH net-next] net: convert dev->rtnl_link_state to a bool Jakub Kicinski
@ 2025-04-10 15:45 ` Stanislav Fomichev
0 siblings, 0 replies; 2+ messages in thread
From: Stanislav Fomichev @ 2025-04-10 15:45 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, sdf,
kuniyu
On 04/09, Jakub Kicinski wrote:
> netdevice reg_state was split into two 16 bit enums back in 2010
> in commit a2835763e130 ("rtnetlink: handle rtnl_link netlink
> notifications manually"). Since the split the fields have been
> moved apart, and last year we converted reg_state to a normal
> u8 in commit 4d42b37def70 ("net: convert dev->reg_state to u8").
>
> rtnl_link_state being a 16 bitfield makes no sense. Convert it
> to a single bool, it seems very unlikely after 15 years that
> we'll need more values in it.
>
> We could drop dev->rtnl_link_ops from the conditions but feels
> like having it there more clearly points at the reason for this
> hack.
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
But for me having rtnl_link_ops in the mix is still hard to read.
Might be more clear to rename rtnl_link_initializing to
suppress_rtnl_notify, make it false by default, and set to true
from rtnl_create_link. Then reading conditions like the one below
will make more sense (imo):
if (!dev->suppress_rtnl_notify)
rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U, GFP_KERNEL, 0, NULL);
(iow, reverse the conditional so false works for most non-ops devices)
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-04-10 15:45 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-10 1:42 [PATCH net-next] net: convert dev->rtnl_link_state to a bool Jakub Kicinski
2025-04-10 15:45 ` Stanislav Fomichev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).