diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-12-07 18:08:17 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-08 20:19:20 -0500 |
commit | 3644f0cee77494190452de132e82245107939284 (patch) | |
tree | 7aeb1dd32c68e372cc2aaa9d26703dd238b48a53 /include/net/neighbour.h | |
parent | eb991b39385c7b04923d701764a34694ec54b53d (diff) |
[NET]: Convert hh_lock to seqlock.
The hard header cache is in the main output path, so using
seqlock instead of reader/writer lock should reduce overhead.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/neighbour.h')
-rw-r--r-- | include/net/neighbour.h | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 23967031ddb7..3725b93c52f3 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h | |||
@@ -309,6 +309,24 @@ static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) | |||
309 | return 0; | 309 | return 0; |
310 | } | 310 | } |
311 | 311 | ||
312 | static inline int neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb) | ||
313 | { | ||
314 | unsigned seq; | ||
315 | int hh_len; | ||
316 | |||
317 | do { | ||
318 | int hh_alen; | ||
319 | |||
320 | seq = read_seqbegin(&hh->hh_lock); | ||
321 | hh_len = hh->hh_len; | ||
322 | hh_alen = HH_DATA_ALIGN(hh_len); | ||
323 | memcpy(skb->data - hh_alen, hh->hh_data, hh_alen); | ||
324 | } while (read_seqretry(&hh->hh_lock, seq)); | ||
325 | |||
326 | skb_push(skb, hh_len); | ||
327 | return hh->hh_output(skb); | ||
328 | } | ||
329 | |||
312 | static inline struct neighbour * | 330 | static inline struct neighbour * |
313 | __neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat) | 331 | __neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat) |
314 | { | 332 | { |