diff options
author | Eric Dumazet <edumazet@google.com> | 2024-05-03 22:20:57 +0300 |
---|---|---|
committer | Paolo Abeni <pabeni@redhat.com> | 2024-05-07 12:14:50 +0300 |
commit | 6890ab31d1a35444741e6150db19d64797db2919 (patch) | |
tree | 9f0e4ae240841eb23698a9c4e45115929997b525 /net/core/rtnetlink.c | |
parent | 6747a5d4990b8c8d7392f7a06b7a4bb5f4ada80e (diff) | |
download | linux-6890ab31d1a35444741e6150db19d64797db2919.tar.xz |
rtnetlink: do not depend on RTNL in rtnl_fill_proto_down()
Change dev_change_proto_down() and dev_change_proto_down_reason()
to write once on dev->proto_down and dev->proto_down_reason.
Then rtnl_fill_proto_down() can use READ_ONCE() annotations
and run locklessly.
rtnl_proto_down_size() should assume worst case,
because readng dev->proto_down_reason multiple
times would be racy without RTNL in the future.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r-- | net/core/rtnetlink.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 16b5f9c68bbf..dfdd08006fae 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1036,8 +1036,8 @@ static size_t rtnl_proto_down_size(const struct net_device *dev) { size_t size = nla_total_size(1); - if (dev->proto_down_reason) - size += nla_total_size(0) + nla_total_size(4); + /* Assume dev->proto_down_reason is not zero. */ + size += nla_total_size(0) + nla_total_size(4); return size; } @@ -1737,10 +1737,10 @@ static int rtnl_fill_proto_down(struct sk_buff *skb, struct nlattr *pr; u32 preason; - if (nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down)) + if (nla_put_u8(skb, IFLA_PROTO_DOWN, READ_ONCE(dev->proto_down))) goto nla_put_failure; - preason = dev->proto_down_reason; + preason = READ_ONCE(dev->proto_down_reason); if (!preason) return 0; |