From: Eric Dumazet <edumazet@google.com>
To: Kuniyuki Iwashima <kuniyu@amazon.com>
Cc: "David S. Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>,
Kuniyuki Iwashima <kuni1840@gmail.com>,
netdev@vger.kernel.org
Subject: Re: [PATCH v1 net-next 13/13] rtnetlink: Protect struct rtnl_af_ops with SRCU.
Date: Thu, 10 Oct 2024 15:16:20 +0200 [thread overview]
Message-ID: <CANn89iJUX3nkQJDOTsj9RN0dH4_u=mVQd4Z9m_mMCLm60Eppug@mail.gmail.com> (raw)
In-Reply-To: <20241009231656.57830-14-kuniyu@amazon.com>
On Thu, Oct 10, 2024 at 1:21 AM Kuniyuki Iwashima <kuniyu@amazon.com> wrote:
>
> Once RTNL is replaced with rtnl_net_lock(), we need a mechanism to
> guarantee that rtnl_af_ops is alive during inflight RTM_SETLINK
> even when its module is being unloaded.
>
> Let's use SRCU to protect rtnl_af_ops.
>
> rtnl_af_lookup() now iterates rtnl_af_ops under RCU and returns
> SRCU-protected ops pointer. The caller must call rtnl_af_put()
> to release the pointer after the use.
>
> Also, rtnl_af_unregister() unlinks the ops first and calls
> synchronize_srcu() to wait for inflight RTM_SETLINK requests to
> complete.
>
> Note that rtnl_af_ops needs to be protected by its dedicated lock
> when RTNL is removed.
>
> Note also that BUG_ON() in do_setlink() is changed to the normal
> error handling as a different af_ops might be found after
> validate_linkmsg().
>
> Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
> ---
> include/net/rtnetlink.h | 5 +++-
> net/core/rtnetlink.c | 58 +++++++++++++++++++++++++++++------------
> 2 files changed, 46 insertions(+), 17 deletions(-)
>
> diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
> index c873fd6193ed..407a2f56f00a 100644
> --- a/include/net/rtnetlink.h
> +++ b/include/net/rtnetlink.h
> @@ -150,7 +150,8 @@ void rtnl_link_unregister(struct rtnl_link_ops *ops);
> /**
> * struct rtnl_af_ops - rtnetlink address family operations
> *
> - * @list: Used internally
> + * @list: Used internally, protected by RTNL and SRCU
> + * @srcu: Used internally
> * @family: Address family
> * @fill_link_af: Function to fill IFLA_AF_SPEC with address family
> * specific netlink attributes.
> @@ -163,6 +164,8 @@ void rtnl_link_unregister(struct rtnl_link_ops *ops);
> */
> struct rtnl_af_ops {
> struct list_head list;
> + struct srcu_struct srcu;
> +
> int family;
>
> int (*fill_link_af)(struct sk_buff *skb,
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index a0702e531331..817165f6d5ef 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -660,18 +660,31 @@ static size_t rtnl_link_get_size(const struct net_device *dev)
>
> static LIST_HEAD(rtnl_af_ops);
>
> -static const struct rtnl_af_ops *rtnl_af_lookup(const int family)
> +static struct rtnl_af_ops *rtnl_af_lookup(const int family, int *srcu_index)
> {
> - const struct rtnl_af_ops *ops;
> + struct rtnl_af_ops *ops;
>
> ASSERT_RTNL();
>
> - list_for_each_entry(ops, &rtnl_af_ops, list) {
> - if (ops->family == family)
> - return ops;
> + rcu_read_lock();
> +
> + list_for_each_entry_rcu(ops, &rtnl_af_ops, list) {
> + if (ops->family == family) {
> + *srcu_index = srcu_read_lock(&ops->srcu);
> + goto unlock;
> + }
> }
>
> - return NULL;
> + ops = NULL;
> +unlock:
> + rcu_read_unlock();
> +
> + return ops;
> +}
> +
> +static void rtnl_af_put(struct rtnl_af_ops *ops, int srcu_index)
> +{
> + srcu_read_unlock(&ops->srcu, srcu_index);
> }
>
> /**
> @@ -683,6 +696,7 @@ static const struct rtnl_af_ops *rtnl_af_lookup(const int family)
> void rtnl_af_register(struct rtnl_af_ops *ops)
> {
> rtnl_lock();
> + init_srcu_struct(&ops->srcu);
Same remark, this could fail.
next prev parent reply other threads:[~2024-10-10 13:16 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-09 23:16 [PATCH v1 net-next 00/13] rtnetlink: Refactor rtnl_{new,del,set}link() for per-netns RTNL Kuniyuki Iwashima
2024-10-09 23:16 ` [PATCH v1 net-next 01/13] rtnetlink: Allocate linkinfo[] as struct rtnl_newlink_tbs Kuniyuki Iwashima
2024-10-10 12:36 ` Eric Dumazet
2024-10-09 23:16 ` [PATCH v1 net-next 02/13] rtnetlink: Call validate_linkmsg() in do_setlink() Kuniyuki Iwashima
2024-10-10 12:44 ` Eric Dumazet
2024-10-09 23:16 ` [PATCH v1 net-next 03/13] rtnetlink: Factorise do_setlink() path from __rtnl_newlink() Kuniyuki Iwashima
2024-10-10 12:39 ` Eric Dumazet
2024-10-09 23:16 ` [PATCH v1 net-next 04/13] rtnetlink: Move simple validation from __rtnl_newlink() to rtnl_newlink() Kuniyuki Iwashima
2024-10-10 12:40 ` Eric Dumazet
2024-10-09 23:16 ` [PATCH v1 net-next 05/13] rtnetlink: Move rtnl_link_ops_get() and retry " Kuniyuki Iwashima
2024-10-09 23:16 ` [PATCH v1 net-next 06/13] rtnetlink: Move ops->validate " Kuniyuki Iwashima
2024-10-10 12:48 ` Eric Dumazet
2024-10-09 23:16 ` [PATCH v1 net-next 07/13] rtnetlink: Protect struct rtnl_link_ops with SRCU Kuniyuki Iwashima
2024-10-10 13:02 ` Eric Dumazet
2024-10-10 16:20 ` Kuniyuki Iwashima
2024-10-09 23:16 ` [PATCH v1 net-next 08/13] rtnetlink: Call rtnl_link_get_net_capable() in rtnl_newlink() Kuniyuki Iwashima
2024-10-10 13:08 ` Eric Dumazet
2024-10-09 23:16 ` [PATCH v1 net-next 09/13] rtnetlink: Fetch IFLA_LINK_NETNSID " Kuniyuki Iwashima
2024-10-10 13:09 ` Eric Dumazet
2024-10-09 23:16 ` [PATCH v1 net-next 10/13] rtnetlink: Clean up rtnl_dellink() Kuniyuki Iwashima
2024-10-10 13:10 ` Eric Dumazet
2024-10-09 23:16 ` [PATCH v1 net-next 11/13] rtnetlink: Clean up rtnl_setlink() Kuniyuki Iwashima
2024-10-10 13:11 ` Eric Dumazet
2024-10-09 23:16 ` [PATCH v1 net-next 12/13] rtnetlink: Call rtnl_link_get_net_capable() in do_setlink() Kuniyuki Iwashima
2024-10-10 13:15 ` Eric Dumazet
2024-10-11 7:36 ` kernel test robot
2024-10-11 16:17 ` Kuniyuki Iwashima
2024-10-09 23:16 ` [PATCH v1 net-next 13/13] rtnetlink: Protect struct rtnl_af_ops with SRCU Kuniyuki Iwashima
2024-10-10 13:16 ` Eric Dumazet [this message]
2024-10-10 16:27 ` Kuniyuki Iwashima
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CANn89iJUX3nkQJDOTsj9RN0dH4_u=mVQd4Z9m_mMCLm60Eppug@mail.gmail.com' \
--to=edumazet@google.com \
--cc=davem@davemloft.net \
--cc=kuba@kernel.org \
--cc=kuni1840@gmail.com \
--cc=kuniyu@amazon.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).