diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-06-03 04:09:10 (GMT) |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-04 03:01:52 (GMT) |
commit | faa9dcf793beba05f7178b63a59eaa3ca5175b6a (patch) | |
tree | 0addd3f98e77ab34a8686eaf6855896efe2f9c4f /net/ipv4 | |
parent | 4736022844fe694c4ee971fa2b6c1cb38dadbc78 (diff) | |
download | linux-faa9dcf793beba05f7178b63a59eaa3ca5175b6a.tar.xz |
arp: RCU changes
Avoid two atomic ops in arp_fwd_proxy()
Avoid two atomic ops in arp_process()
Valid optims since arp_rcv() is run under rcu_read_lock()
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/arp.c | 11 |
1 files changed, 4 insertions, 7 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index f094b75..917d2d6 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -545,10 +545,10 @@ static inline int arp_fwd_proxy(struct in_device *in_dev, /* place to check for proxy_arp for routes */ - if ((out_dev = in_dev_get(rt->u.dst.dev)) != NULL) { + out_dev = __in_dev_get_rcu(rt->u.dst.dev); + if (out_dev) omi = IN_DEV_MEDIUM_ID(out_dev); - in_dev_put(out_dev); - } + return (omi != imi && omi != -1); } @@ -741,7 +741,7 @@ void arp_send(int type, int ptype, __be32 dest_ip, static int arp_process(struct sk_buff *skb) { struct net_device *dev = skb->dev; - struct in_device *in_dev = in_dev_get(dev); + struct in_device *in_dev = __in_dev_get_rcu(dev); struct arphdr *arp; unsigned char *arp_ptr; struct rtable *rt; @@ -890,7 +890,6 @@ static int arp_process(struct sk_buff *skb) arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha); } else { pneigh_enqueue(&arp_tbl, in_dev->arp_parms, skb); - in_dev_put(in_dev); return 0; } goto out; @@ -936,8 +935,6 @@ static int arp_process(struct sk_buff *skb) } out: - if (in_dev) - in_dev_put(in_dev); consume_skb(skb); return 0; } |