summaryrefslogtreecommitdiff
path: root/include/net/neighbour.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/neighbour.h')
-rw-r--r--include/net/neighbour.h14
1 files changed, 9 insertions, 5 deletions
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 344d8988842a..0dab173e27da 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -334,18 +334,22 @@ static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb)
}
#endif
-static inline int neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb)
+static inline int neigh_hh_output(const struct hh_cache *hh, struct sk_buff *skb)
{
unsigned int seq;
int hh_len;
do {
- int hh_alen;
-
seq = read_seqbegin(&hh->hh_lock);
hh_len = hh->hh_len;
- hh_alen = HH_DATA_ALIGN(hh_len);
- memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
+ if (likely(hh_len <= HH_DATA_MOD)) {
+ /* this is inlined by gcc */
+ memcpy(skb->data - HH_DATA_MOD, hh->hh_data, HH_DATA_MOD);
+ } else {
+ int hh_alen = HH_DATA_ALIGN(hh_len);
+
+ memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
+ }
} while (read_seqretry(&hh->hh_lock, seq));
skb_push(skb, hh_len);