aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-06-22 03:43:15 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-26 00:33:16 -0400
commit4b4194c40f4ac8d03a700845f8978cba53246b5a (patch)
tree11beaa1417395708bc6af1d9fcc1da401b9bc1d6 /net/ipv4
parent59b80802a8a18b64d38b51aa168253684b2649d5 (diff)
arp: RCU change in arp_solicit()
Avoid two atomic ops in arp_solicit() 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.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index cf78f41830ca..09ead1baa99e 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -333,11 +333,14 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
333 struct net_device *dev = neigh->dev; 333 struct net_device *dev = neigh->dev;
334 __be32 target = *(__be32*)neigh->primary_key; 334 __be32 target = *(__be32*)neigh->primary_key;
335 int probes = atomic_read(&neigh->probes); 335 int probes = atomic_read(&neigh->probes);
336 struct in_device *in_dev = in_dev_get(dev); 336 struct in_device *in_dev;
337 337
338 if (!in_dev) 338 rcu_read_lock();
339 in_dev = __in_dev_get_rcu(dev);
340 if (!in_dev) {
341 rcu_read_unlock();
339 return; 342 return;
340 343 }
341 switch (IN_DEV_ARP_ANNOUNCE(in_dev)) { 344 switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
342 default: 345 default:
343 case 0: /* By default announce any local IP */ 346 case 0: /* By default announce any local IP */
@@ -358,9 +361,8 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
358 case 2: /* Avoid secondary IPs, get a primary/preferred one */ 361 case 2: /* Avoid secondary IPs, get a primary/preferred one */
359 break; 362 break;
360 } 363 }
364 rcu_read_unlock();
361 365
362 if (in_dev)
363 in_dev_put(in_dev);
364 if (!saddr) 366 if (!saddr)
365 saddr = inet_select_addr(dev, target, RT_SCOPE_LINK); 367 saddr = inet_select_addr(dev, target, RT_SCOPE_LINK);
366 368