ipv6: Take table lock outside of sernum update function
authorIdo Schimmel <idosch@mellanox.com>
Sun, 7 Jan 2018 10:45:14 +0000 (12:45 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 8 Jan 2018 02:29:41 +0000 (21:29 -0500)
The next patch is going to allow dead routes to remain in the FIB tree
in certain situations.

When this happens we need to be sure to bump the sernum of the nodes
where these are stored so that potential copies cached in sockets are
invalidated.

The function that performs this update assumes the table lock is not
taken when it is invoked, but that will not be the case when it is
invoked by the tree walker.

Have the function assume the lock is taken and make the single caller
take the lock itself.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Acked-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv6/ip6_fib.c
net/ipv6/route.c

index c1bbe7bf9fddce279c67544a132747cd7460818c..edda5ad3b405f5839f3b1591c615850483ae5cdc 100644 (file)
@@ -107,16 +107,13 @@ enum {
 
 void fib6_update_sernum(struct rt6_info *rt)
 {
-       struct fib6_table *table = rt->rt6i_table;
        struct net *net = dev_net(rt->dst.dev);
        struct fib6_node *fn;
 
-       spin_lock_bh(&table->tb6_lock);
        fn = rcu_dereference_protected(rt->rt6i_node,
-                       lockdep_is_held(&table->tb6_lock));
+                       lockdep_is_held(&rt->rt6i_table->tb6_lock));
        if (fn)
                fn->fn_sernum = fib6_new_sernum(net);
-       spin_unlock_bh(&table->tb6_lock);
 }
 
 /*
index f62d24948aa25427b17bba8b463891a2948ae2b5..a3bfce71c86181911ab7a7be6c80949b54c0d404 100644 (file)
@@ -1353,7 +1353,9 @@ out:
 
        /* Update fn->fn_sernum to invalidate all cached dst */
        if (!err) {
+               spin_lock_bh(&ort->rt6i_table->tb6_lock);
                fib6_update_sernum(ort);
+               spin_unlock_bh(&ort->rt6i_table->tb6_lock);
                fib6_force_start_gc(net);
        }