]> www.infradead.org Git - nvme.git/commitdiff
rtnetlink: move rtnl_lock handling out of af_netlink
authorJakub Kicinski <kuba@kernel.org>
Thu, 6 Jun 2024 19:29:05 +0000 (12:29 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 10 Jun 2024 12:15:40 +0000 (13:15 +0100)
Now that we have an intermediate layer of code for handling
rtnl-level netlink dump quirks, we can move the rtnl_lock
taking there.

For dump handlers with RTNL_FLAG_DUMP_SPLIT_NLM_DONE we can
avoid taking rtnl_lock just to generate NLM_DONE, once again.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/rtnetlink.c
net/netlink/af_netlink.c

index 4668d671804070d978d4e1f0f46200dbb496145a..eabfc8290f5e29f2ef3e5c1481715ae9056ea689 100644 (file)
@@ -6486,6 +6486,7 @@ static int rtnl_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh,
 
 static int rtnl_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       const bool needs_lock = !(cb->flags & RTNL_FLAG_DUMP_UNLOCKED);
        rtnl_dumpit_func dumpit = cb->data;
        int err;
 
@@ -6495,7 +6496,11 @@ static int rtnl_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
        if (!dumpit)
                return 0;
 
+       if (needs_lock)
+               rtnl_lock();
        err = dumpit(skb, cb);
+       if (needs_lock)
+               rtnl_unlock();
 
        /* Old dump handlers used to send NLM_DONE as in a separate recvmsg().
         * Some applications which parse netlink manually depend on this.
@@ -6515,7 +6520,8 @@ static int rtnetlink_dump_start(struct sock *ssk, struct sk_buff *skb,
                                const struct nlmsghdr *nlh,
                                struct netlink_dump_control *control)
 {
-       if (control->flags & RTNL_FLAG_DUMP_SPLIT_NLM_DONE) {
+       if (control->flags & RTNL_FLAG_DUMP_SPLIT_NLM_DONE ||
+           !(control->flags & RTNL_FLAG_DUMP_UNLOCKED)) {
                WARN_ON(control->data);
                control->data = control->dump;
                control->dump = rtnl_dumpit;
@@ -6703,7 +6709,6 @@ static int __net_init rtnetlink_net_init(struct net *net)
        struct netlink_kernel_cfg cfg = {
                .groups         = RTNLGRP_MAX,
                .input          = rtnetlink_rcv,
-               .cb_mutex       = &rtnl_mutex,
                .flags          = NL_CFG_F_NONROOT_RECV,
                .bind           = rtnetlink_bind,
        };
index fa9c090cf629e6e92c097285b262ed90324c7656..8bbbe75e75dbe8c286f7188a61db35740250514c 100644 (file)
@@ -2330,8 +2330,6 @@ static int netlink_dump(struct sock *sk, bool lock_taken)
 
                cb->extack = &extack;
 
-               if (cb->flags & RTNL_FLAG_DUMP_UNLOCKED)
-                       extra_mutex = NULL;
                if (extra_mutex)
                        mutex_lock(extra_mutex);
                nlk->dump_done_errno = cb->dump(skb, cb);