From 5c25f686db352082eef8daa21b760192351a023a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 13 Jul 2011 00:51:10 -0700 Subject: net: Kill support for multiple hh_cache entries per neighbour This never, ever, happens. Neighbour entries are always tied to one address family, and therefore one set of dst_ops, and therefore one dst_ops->protocol "hh_type" value. This capability was blindly imported by Alexey Kuznetsov when he wrote the neighbour layer. Signed-off-by: David S. Miller --- net/core/neighbour.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'net/core') diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 8f7e1d8d92a..f879bb55299 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -702,9 +702,9 @@ void neigh_destroy(struct neighbour *neigh) if (neigh_del_timer(neigh)) printk(KERN_WARNING "Impossible event.\n"); - while ((hh = neigh->hh) != NULL) { - neigh->hh = hh->hh_next; - hh->hh_next = NULL; + hh = neigh->hh; + if (hh) { + neigh->hh = NULL; write_seqlock_bh(&hh->hh_lock); hh->hh_output = neigh_blackhole; @@ -737,7 +737,8 @@ static void neigh_suspect(struct neighbour *neigh) neigh->output = neigh->ops->output; - for (hh = neigh->hh; hh; hh = hh->hh_next) + hh = neigh->hh; + if (hh) hh->hh_output = neigh->ops->output; } @@ -754,7 +755,8 @@ static void neigh_connect(struct neighbour *neigh) neigh->output = neigh->ops->connected_output; - for (hh = neigh->hh; hh; hh = hh->hh_next) + hh = neigh->hh; + if (hh) hh->hh_output = neigh->ops->hh_output; } @@ -1025,7 +1027,8 @@ static void neigh_update_hhs(const struct neighbour *neigh) update = neigh->dev->header_ops->cache_update; if (update) { - for (hh = neigh->hh; hh; hh = hh->hh_next) { + hh = neigh->hh; + if (hh) { write_seqlock_bh(&hh->hh_lock); update(hh, neigh->dev, neigh->ha); write_sequnlock_bh(&hh->hh_lock); @@ -1211,19 +1214,17 @@ struct neighbour *neigh_event_ns(struct neigh_table *tbl, } EXPORT_SYMBOL(neigh_event_ns); -static inline bool neigh_hh_lookup(struct neighbour *n, struct dst_entry *dst, - __be16 protocol) +static inline bool neigh_hh_lookup(struct neighbour *n, struct dst_entry *dst) { struct hh_cache *hh; smp_rmb(); /* paired with smp_wmb() in neigh_hh_init() */ - for (hh = n->hh; hh; hh = hh->hh_next) { - if (hh->hh_type == protocol) { - atomic_inc(&hh->hh_refcnt); - if (unlikely(cmpxchg(&dst->hh, NULL, hh) != NULL)) - hh_cache_put(hh); - return true; - } + hh = n->hh; + if (hh) { + atomic_inc(&hh->hh_refcnt); + if (unlikely(cmpxchg(&dst->hh, NULL, hh) != NULL)) + hh_cache_put(hh); + return true; } return false; } @@ -1235,7 +1236,7 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, struct hh_cache *hh; struct net_device *dev = dst->dev; - if (likely(neigh_hh_lookup(n, dst, protocol))) + if (likely(neigh_hh_lookup(n, dst))) return; /* slow path */ @@ -1244,7 +1245,6 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, return; seqlock_init(&hh->hh_lock); - hh->hh_type = protocol; atomic_set(&hh->hh_refcnt, 2); if (dev->header_ops->cache(n, hh, protocol)) { @@ -1255,7 +1255,7 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, write_lock_bh(&n->lock); /* must check if another thread already did the insert */ - if (neigh_hh_lookup(n, dst, protocol)) { + if (neigh_hh_lookup(n, dst)) { kfree(hh); goto end; } @@ -1265,7 +1265,6 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, else hh->hh_output = n->ops->output; - hh->hh_next = n->hh; smp_wmb(); /* paired with smp_rmb() in neigh_hh_lookup() */ n->hh = hh; -- cgit v1.2.3