From c8c8fa67a0878839393574db74d61cea53f82589 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Sat, 25 Jun 2011 13:18:12 +0000 Subject: [PATCH] --- yaml --- r: 256250 b: refs/heads/master c: 064b43304ed8ede8e13ff7b4338d09fd37bcffb1 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/net/igb/e1000_82575.c | 1 + trunk/include/net/arp.h | 7 ----- trunk/include/net/neighbour.h | 2 +- trunk/net/core/neighbour.c | 48 ++++++++++++++--------------- trunk/net/ipv4/arp.c | 3 +- 6 files changed, 29 insertions(+), 34 deletions(-) diff --git a/[refs] b/[refs] index 0e444e2003ea..d98d30015b38 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f610b74b14d74a069f61583131e689550fd5bab3 +refs/heads/master: 064b43304ed8ede8e13ff7b4338d09fd37bcffb1 diff --git a/trunk/drivers/net/igb/e1000_82575.c b/trunk/drivers/net/igb/e1000_82575.c index 0f563c8c5ffc..493e331d7064 100644 --- a/trunk/drivers/net/igb/e1000_82575.c +++ b/trunk/drivers/net/igb/e1000_82575.c @@ -1735,6 +1735,7 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw) ctrl |= E1000_CTRL_RST; wr32(E1000_CTRL, ctrl); + wrfl(); /* Add delay to insure DEV_RST has time to complete */ if (global_device_reset) diff --git a/trunk/include/net/arp.h b/trunk/include/net/arp.h index 723bde501c64..91f0568a04ef 100644 --- a/trunk/include/net/arp.h +++ b/trunk/include/net/arp.h @@ -8,13 +8,6 @@ extern struct neigh_table arp_tbl; -static inline u32 arp_hashfn(u32 key, const struct net_device *dev, u32 hash_rnd) -{ - u32 val = key ^ dev->ifindex; - - return val * hash_rnd; -} - extern void arp_init(void); extern int arp_find(unsigned char *haddr, struct sk_buff *skb); extern int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg); diff --git a/trunk/include/net/neighbour.h b/trunk/include/net/neighbour.h index 6fe8c2cd5acb..4014b623880c 100644 --- a/trunk/include/net/neighbour.h +++ b/trunk/include/net/neighbour.h @@ -142,7 +142,7 @@ struct pneigh_entry { struct neigh_hash_table { struct neighbour __rcu **hash_buckets; - unsigned int hash_shift; + unsigned int hash_mask; __u32 hash_rnd; struct rcu_head rcu; }; diff --git a/trunk/net/core/neighbour.c b/trunk/net/core/neighbour.c index 50bd960983e0..ceb505b1507c 100644 --- a/trunk/net/core/neighbour.c +++ b/trunk/net/core/neighbour.c @@ -137,7 +137,7 @@ static int neigh_forced_gc(struct neigh_table *tbl) write_lock_bh(&tbl->lock); nht = rcu_dereference_protected(tbl->nht, lockdep_is_held(&tbl->lock)); - for (i = 0; i < (1 << nht->hash_shift); i++) { + for (i = 0; i <= nht->hash_mask; i++) { struct neighbour *n; struct neighbour __rcu **np; @@ -210,7 +210,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev) nht = rcu_dereference_protected(tbl->nht, lockdep_is_held(&tbl->lock)); - for (i = 0; i < (1 << nht->hash_shift); i++) { + for (i = 0; i <= nht->hash_mask; i++) { struct neighbour *n; struct neighbour __rcu **np = &nht->hash_buckets[i]; @@ -312,9 +312,9 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl) goto out; } -static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift) +static struct neigh_hash_table *neigh_hash_alloc(unsigned int entries) { - size_t size = (1 << shift) * sizeof(struct neighbour *); + size_t size = entries * sizeof(struct neighbour *); struct neigh_hash_table *ret; struct neighbour __rcu **buckets; @@ -332,9 +332,8 @@ static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift) return NULL; } ret->hash_buckets = buckets; - ret->hash_shift = shift; + ret->hash_mask = entries - 1; get_random_bytes(&ret->hash_rnd, sizeof(ret->hash_rnd)); - ret->hash_rnd |= 1; return ret; } @@ -343,7 +342,7 @@ static void neigh_hash_free_rcu(struct rcu_head *head) struct neigh_hash_table *nht = container_of(head, struct neigh_hash_table, rcu); - size_t size = (1 << nht->hash_shift) * sizeof(struct neighbour *); + size_t size = (nht->hash_mask + 1) * sizeof(struct neighbour *); struct neighbour __rcu **buckets = nht->hash_buckets; if (size <= PAGE_SIZE) @@ -354,20 +353,21 @@ static void neigh_hash_free_rcu(struct rcu_head *head) } static struct neigh_hash_table *neigh_hash_grow(struct neigh_table *tbl, - unsigned long new_shift) + unsigned long new_entries) { unsigned int i, hash; struct neigh_hash_table *new_nht, *old_nht; NEIGH_CACHE_STAT_INC(tbl, hash_grows); + BUG_ON(!is_power_of_2(new_entries)); old_nht = rcu_dereference_protected(tbl->nht, lockdep_is_held(&tbl->lock)); - new_nht = neigh_hash_alloc(new_shift); + new_nht = neigh_hash_alloc(new_entries); if (!new_nht) return old_nht; - for (i = 0; i < (1 << old_nht->hash_shift); i++) { + for (i = 0; i <= old_nht->hash_mask; i++) { struct neighbour *n, *next; for (n = rcu_dereference_protected(old_nht->hash_buckets[i], @@ -377,7 +377,7 @@ static struct neigh_hash_table *neigh_hash_grow(struct neigh_table *tbl, hash = tbl->hash(n->primary_key, n->dev, new_nht->hash_rnd); - hash >>= (32 - new_nht->hash_shift); + hash &= new_nht->hash_mask; next = rcu_dereference_protected(n->next, lockdep_is_held(&tbl->lock)); @@ -406,7 +406,7 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, rcu_read_lock_bh(); nht = rcu_dereference_bh(tbl->nht); - hash_val = tbl->hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); + hash_val = tbl->hash(pkey, dev, nht->hash_rnd) & nht->hash_mask; for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); n != NULL; @@ -436,7 +436,7 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, rcu_read_lock_bh(); nht = rcu_dereference_bh(tbl->nht); - hash_val = tbl->hash(pkey, NULL, nht->hash_rnd) >> (32 - nht->hash_shift); + hash_val = tbl->hash(pkey, NULL, nht->hash_rnd) & nht->hash_mask; for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); n != NULL; @@ -492,10 +492,10 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey, nht = rcu_dereference_protected(tbl->nht, lockdep_is_held(&tbl->lock)); - if (atomic_read(&tbl->entries) > (1 << nht->hash_shift)) - nht = neigh_hash_grow(tbl, nht->hash_shift + 1); + if (atomic_read(&tbl->entries) > (nht->hash_mask + 1)) + nht = neigh_hash_grow(tbl, (nht->hash_mask + 1) << 1); - hash_val = tbl->hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); + hash_val = tbl->hash(pkey, dev, nht->hash_rnd) & nht->hash_mask; if (n->parms->dead) { rc = ERR_PTR(-EINVAL); @@ -784,7 +784,7 @@ static void neigh_periodic_work(struct work_struct *work) neigh_rand_reach_time(p->base_reachable_time); } - for (i = 0 ; i < (1 << nht->hash_shift); i++) { + for (i = 0 ; i <= nht->hash_mask; i++) { np = &nht->hash_buckets[i]; while ((n = rcu_dereference_protected(*np, @@ -1540,7 +1540,7 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl) panic("cannot create neighbour proc dir entry"); #endif - RCU_INIT_POINTER(tbl->nht, neigh_hash_alloc(3)); + RCU_INIT_POINTER(tbl->nht, neigh_hash_alloc(8)); phsize = (PNEIGH_HASHMASK + 1) * sizeof(struct pneigh_entry *); tbl->phash_buckets = kzalloc(phsize, GFP_KERNEL); @@ -1857,7 +1857,7 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, rcu_read_lock_bh(); nht = rcu_dereference_bh(tbl->nht); ndc.ndtc_hash_rnd = nht->hash_rnd; - ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1); + ndc.ndtc_hash_mask = nht->hash_mask; rcu_read_unlock_bh(); NLA_PUT(skb, NDTA_CONFIG, sizeof(ndc), &ndc); @@ -2200,7 +2200,7 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, rcu_read_lock_bh(); nht = rcu_dereference_bh(tbl->nht); - for (h = 0; h < (1 << nht->hash_shift); h++) { + for (h = 0; h <= nht->hash_mask; h++) { if (h < s_h) continue; if (h > s_h) @@ -2264,7 +2264,7 @@ void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void nht = rcu_dereference_bh(tbl->nht); read_lock(&tbl->lock); /* avoid resizes */ - for (chain = 0; chain < (1 << nht->hash_shift); chain++) { + for (chain = 0; chain <= nht->hash_mask; chain++) { struct neighbour *n; for (n = rcu_dereference_bh(nht->hash_buckets[chain]); @@ -2286,7 +2286,7 @@ void __neigh_for_each_release(struct neigh_table *tbl, nht = rcu_dereference_protected(tbl->nht, lockdep_is_held(&tbl->lock)); - for (chain = 0; chain < (1 << nht->hash_shift); chain++) { + for (chain = 0; chain <= nht->hash_mask; chain++) { struct neighbour *n; struct neighbour __rcu **np; @@ -2323,7 +2323,7 @@ static struct neighbour *neigh_get_first(struct seq_file *seq) int bucket = state->bucket; state->flags &= ~NEIGH_SEQ_IS_PNEIGH; - for (bucket = 0; bucket < (1 << nht->hash_shift); bucket++) { + for (bucket = 0; bucket <= nht->hash_mask; bucket++) { n = rcu_dereference_bh(nht->hash_buckets[bucket]); while (n) { @@ -2390,7 +2390,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq, if (n) break; - if (++state->bucket >= (1 << nht->hash_shift)) + if (++state->bucket > nht->hash_mask) break; n = rcu_dereference_bh(nht->hash_buckets[state->bucket]); diff --git a/trunk/net/ipv4/arp.c b/trunk/net/ipv4/arp.c index 4412b57f6ff6..1b74d3b64371 100644 --- a/trunk/net/ipv4/arp.c +++ b/trunk/net/ipv4/arp.c @@ -97,6 +97,7 @@ #include #include #include +#include #include #ifdef CONFIG_SYSCTL #include @@ -231,7 +232,7 @@ static u32 arp_hash(const void *pkey, const struct net_device *dev, __u32 hash_rnd) { - return arp_hashfn(*(u32 *)pkey, dev, hash_rnd); + return jhash_2words(*(u32 *)pkey, dev->ifindex, hash_rnd); } static int arp_constructor(struct neighbour *neigh)