summaryrefslogtreecommitdiffstats
path: root/net/ipv4/arp.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-10-07 10:44:07 +0000
committerDavid S. Miller <davem@davemloft.net>2010-10-11 12:54:04 -0700
commit0ed8ddf4045fcfcac36bad753dc4046118c603ec (patch)
treecf1d9eb14668c4d2257b3519ed7deec8c5cb396d /net/ipv4/arp.c
parentd122179a3c0fdc71b88cb9e3605f372b1651a9ff (diff)
downloadlinux-0ed8ddf4045fcfcac36bad753dc4046118c603ec.tar.gz
linux-0ed8ddf4045fcfcac36bad753dc4046118c603ec.tar.bz2
linux-0ed8ddf4045fcfcac36bad753dc4046118c603ec.zip
neigh: Protect neigh->ha[] with a seqlock
Add a seqlock in struct neighbour to protect neigh->ha[], and avoid dirtying neighbour in stress situation (many different flows / dsts) Dirtying takes place because of read_lock(&n->lock) and n->used writes. Switching to a seqlock, and writing n->used only on jiffies changes permits less dirtying. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/arp.c')
-rw-r--r--net/ipv4/arp.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index f35309578170..d8e540c5b071 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -502,10 +502,8 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb)
if (n) {
n->used = jiffies;
- if (n->nud_state&NUD_VALID || neigh_event_send(n, skb) == 0) {
- read_lock_bh(&n->lock);
- memcpy(haddr, n->ha, dev->addr_len);
- read_unlock_bh(&n->lock);
+ if (n->nud_state & NUD_VALID || neigh_event_send(n, skb) == 0) {
+ neigh_ha_snapshot(haddr, n, dev);
neigh_release(n);
return 0;
}