aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2009-11-02 05:21:37 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-02 06:42:40 -0500
commitf1a28eab20076542322fcab3efa016834bd732f2 (patch)
treeda94305517418449975ceaeabe61ea6d1547cd67 /net/ipv6
parent654d1f8a019dfa06df8355248e1ce222f303b88d (diff)
ip6tnl: less dev_put() calls
Using dev_get_by_index_rcu() in ip6_tnl_rcv_ctl() & ip6_tnl_xmit_ctl() avoids touching device refcount. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ip6_tunnel.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 6c1b5c98e818..1d614113a4ba 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -658,6 +658,7 @@ static void ip6ip6_dscp_ecn_decapsulate(struct ip6_tnl *t,
658 IP6_ECN_set_ce(ipv6_hdr(skb)); 658 IP6_ECN_set_ce(ipv6_hdr(skb));
659} 659}
660 660
661/* called with rcu_read_lock() */
661static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t) 662static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
662{ 663{
663 struct ip6_tnl_parm *p = &t->parms; 664 struct ip6_tnl_parm *p = &t->parms;
@@ -668,15 +669,13 @@ static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
668 struct net_device *ldev = NULL; 669 struct net_device *ldev = NULL;
669 670
670 if (p->link) 671 if (p->link)
671 ldev = dev_get_by_index(net, p->link); 672 ldev = dev_get_by_index_rcu(net, p->link);
672 673
673 if ((ipv6_addr_is_multicast(&p->laddr) || 674 if ((ipv6_addr_is_multicast(&p->laddr) ||
674 likely(ipv6_chk_addr(net, &p->laddr, ldev, 0))) && 675 likely(ipv6_chk_addr(net, &p->laddr, ldev, 0))) &&
675 likely(!ipv6_chk_addr(net, &p->raddr, NULL, 0))) 676 likely(!ipv6_chk_addr(net, &p->raddr, NULL, 0)))
676 ret = 1; 677 ret = 1;
677 678
678 if (ldev)
679 dev_put(ldev);
680 } 679 }
681 return ret; 680 return ret;
682} 681}
@@ -804,8 +803,9 @@ static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
804 if (p->flags & IP6_TNL_F_CAP_XMIT) { 803 if (p->flags & IP6_TNL_F_CAP_XMIT) {
805 struct net_device *ldev = NULL; 804 struct net_device *ldev = NULL;
806 805
806 rcu_read_lock();
807 if (p->link) 807 if (p->link)
808 ldev = dev_get_by_index(net, p->link); 808 ldev = dev_get_by_index_rcu(net, p->link);
809 809
810 if (unlikely(!ipv6_chk_addr(net, &p->laddr, ldev, 0))) 810 if (unlikely(!ipv6_chk_addr(net, &p->laddr, ldev, 0)))
811 printk(KERN_WARNING 811 printk(KERN_WARNING
@@ -819,8 +819,7 @@ static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
819 p->name); 819 p->name);
820 else 820 else
821 ret = 1; 821 ret = 1;
822 if (ldev) 822 rcu_read_unlock();
823 dev_put(ldev);
824 } 823 }
825 return ret; 824 return ret;
826} 825}