diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-10-07 06:44:07 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-11 15:54:04 -0400 |
commit | 0ed8ddf4045fcfcac36bad753dc4046118c603ec (patch) | |
tree | cf1d9eb14668c4d2257b3519ed7deec8c5cb396d /net/sched | |
parent | d122179a3c0fdc71b88cb9e3605f372b1651a9ff (diff) |
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/sched')
-rw-r--r-- | net/sched/sch_teql.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index feaabc103ce6..401af9596709 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c | |||
@@ -241,11 +241,11 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device * | |||
241 | } | 241 | } |
242 | if (neigh_event_send(n, skb_res) == 0) { | 242 | if (neigh_event_send(n, skb_res) == 0) { |
243 | int err; | 243 | int err; |
244 | char haddr[MAX_ADDR_LEN]; | ||
244 | 245 | ||
245 | read_lock(&n->lock); | 246 | neigh_ha_snapshot(haddr, n, dev); |
246 | err = dev_hard_header(skb, dev, ntohs(skb->protocol), | 247 | err = dev_hard_header(skb, dev, ntohs(skb->protocol), haddr, |
247 | n->ha, NULL, skb->len); | 248 | NULL, skb->len); |
248 | read_unlock(&n->lock); | ||
249 | 249 | ||
250 | if (err < 0) { | 250 | if (err < 0) { |
251 | neigh_release(n); | 251 | neigh_release(n); |