ipv6: RCU changes in ipv6_get_mtu() and ip6_dst_hoplimit()
authorEric Dumazet <eric.dumazet@gmail.com>
Mon, 14 Jun 2010 04:46:20 +0000 (04:46 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 15 Jun 2010 06:13:07 +0000 (23:13 -0700)
Use RCU to avoid atomic ops on idev refcnt in ipv6_get_mtu()
and ip6_dst_hoplimit()

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv6/route.c

index f7702850d45cefaf880a93d328ac6038c9aad4d5..8f2d0400cf8ae616ad4283a6d846d8fa4b684d40 100644 (file)
@@ -1084,11 +1084,11 @@ static int ipv6_get_mtu(struct net_device *dev)
        int mtu = IPV6_MIN_MTU;
        struct inet6_dev *idev;
 
-       idev = in6_dev_get(dev);
-       if (idev) {
+       rcu_read_lock();
+       idev = __in6_dev_get(dev);
+       if (idev)
                mtu = idev->cnf.mtu6;
-               in6_dev_put(idev);
-       }
+       rcu_read_unlock();
        return mtu;
 }
 
@@ -1097,12 +1097,15 @@ int ip6_dst_hoplimit(struct dst_entry *dst)
        int hoplimit = dst_metric(dst, RTAX_HOPLIMIT);
        if (hoplimit < 0) {
                struct net_device *dev = dst->dev;
-               struct inet6_dev *idev = in6_dev_get(dev);
-               if (idev) {
+               struct inet6_dev *idev;
+
+               rcu_read_lock();
+               idev = __in6_dev_get(dev);
+               if (idev)
                        hoplimit = idev->cnf.hop_limit;
-                       in6_dev_put(idev);
-               } else
+               else
                        hoplimit = dev_net(dev)->ipv6.devconf_all->hop_limit;
+               rcu_read_unlock();
        }
        return hoplimit;
 }