diff mbox series

ipv6: try not to take rtnl_lock in ip6mr_sk_done

Message ID 20171106204059.AED8940382@fruggeri-Arora18_1.sjc.aristanetworks.com
State Changes Requested, archived
Delegated to: David Miller
Headers show
Series ipv6: try not to take rtnl_lock in ip6mr_sk_done | expand

Commit Message

Francesco Ruggeri Nov. 6, 2017, 8:40 p.m. UTC
commit 9634257773c30ce13d74fa4918329612c60d84a8
Author: Francesco Ruggeri <fruggeri@arista.com>
Date:   Mon Nov 6 11:01:59 2017 -0800

    ipv6: try not to take rtnl_lock in ip6mr_sk_done
    
    mrt->mroute6_sk can only be set to a non-NULL value in ip6mr_sk_init()
    if sk->sk_type == SOCK_RAW && inet_sk(sk)->inet_num == IPPROTO_ICMPV6.
    Use that not to unnecessarily take the rtn_lock in ip6mr_sk_done()
    when it is invoked from rawv6_close().

Signed-off-by: Francesco Ruggeri <fruggeri@arista.com>

Comments

Francesco Ruggeri Nov. 8, 2017, 4:29 p.m. UTC | #1
Any comments about this?
The idea is to avoid traversing all mr6_tables (which requires
the rtnl_lock) in ip6mr_sk_done(), when we know in advance
that a match will not be found.
This can happen when rawv6_close()/ip6mr_sk_done() is invoked
on non-mroute6 sockets.

Thanks,
Francesco

On Mon, Nov 6, 2017 at 12:40 PM, Francesco Ruggeri <fruggeri@arista.com> wrote:
> commit 9634257773c30ce13d74fa4918329612c60d84a8
> Author: Francesco Ruggeri <fruggeri@arista.com>
> Date:   Mon Nov 6 11:01:59 2017 -0800
>
>     ipv6: try not to take rtnl_lock in ip6mr_sk_done
>
>     mrt->mroute6_sk can only be set to a non-NULL value in ip6mr_sk_init()
>     if sk->sk_type == SOCK_RAW && inet_sk(sk)->inet_num == IPPROTO_ICMPV6.
>     Use that not to unnecessarily take the rtn_lock in ip6mr_sk_done()
>     when it is invoked from rawv6_close().
>
> Signed-off-by: Francesco Ruggeri <fruggeri@arista.com>
>
> diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
> index f5500f5..e1bb2d8 100644
> --- a/net/ipv6/ip6mr.c
> +++ b/net/ipv6/ip6mr.c
> @@ -1617,6 +1617,10 @@ int ip6mr_sk_done(struct sock *sk)
>         struct net *net = sock_net(sk);
>         struct mr6_table *mrt;
>
> +       if (sk->sk_type != SOCK_RAW ||
> +           inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
> +               return err;
> +
>         rtnl_lock();
>         ip6mr_for_each_table(mrt, net) {
>                 if (sk == mrt->mroute6_sk) {
Eric Dumazet Nov. 8, 2017, 5:34 p.m. UTC | #2
On Wed, 2017-11-08 at 08:29 -0800, Francesco Ruggeri wrote:
> Any comments about this?
> The idea is to avoid traversing all mr6_tables (which requires
> the rtnl_lock) in ip6mr_sk_done(), when we know in advance
> that a match will not be found.
> This can happen when rawv6_close()/ip6mr_sk_done() is invoked
> on non-mroute6 sockets.

Please do not top post on netdev.

Most networking folks are in Seoul, attending netdev 2.2, having beers
and conversations together. Your patch can wait.

Also you did not provide the net or net-next tags.

Most applications do not open/close raw sockets often, so it is not
clear why we should try to optimize this slow path ?
diff mbox series

Patch

diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index f5500f5..e1bb2d8 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1617,6 +1617,10 @@  int ip6mr_sk_done(struct sock *sk)
 	struct net *net = sock_net(sk);
 	struct mr6_table *mrt;
 
+	if (sk->sk_type != SOCK_RAW ||
+	    inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
+		return err;
+
 	rtnl_lock();
 	ip6mr_for_each_table(mrt, net) {
 		if (sk == mrt->mroute6_sk) {