netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stephen Hemminger <shemminger@osdl.org>
To: David Miller <davem@davemloft.net>
Cc: netdev@vger.kernel.org
Subject: [RFC 3/7] neighbour: convert pneigh hash table to hlist
Date: Mon, 14 Aug 2006 14:20:07 -0700	[thread overview]
Message-ID: <20060814212143.416542832@localhost.localdomain> (raw)
In-Reply-To: 20060814212004.606140865@localhost.localdomain

[-- Attachment #1: hlist2.patch --]
[-- Type: text/plain, Size: 5335 bytes --]

Change the pneigh_entry table to hlist from list.h
to allow for easier later conversion to RCU.

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>

---
 include/net/neighbour.h |    6 ++--
 net/core/neighbour.c    |   58 ++++++++++++++++++++++++------------------------
 2 files changed, 33 insertions(+), 31 deletions(-)

--- net-2.6.19.orig/include/net/neighbour.h
+++ net-2.6.19/include/net/neighbour.h
@@ -124,8 +124,8 @@ struct neigh_ops
 
 struct pneigh_entry
 {
-	struct pneigh_entry	*next;
-	struct net_device		*dev;
+	struct hlist_node	hlist;
+	struct net_device	*dev;
 	u8			key[0];
 };
 
@@ -165,7 +165,7 @@ struct neigh_table
 	unsigned int		hash_mask;
 	__u32			hash_rnd;
 	unsigned int		hash_chain_gc;
-	struct pneigh_entry	**phash_buckets;
+	struct hlist_head	*phash_buckets;
 #ifdef CONFIG_PROC_FS
 	struct proc_dir_entry	*pde;
 #endif
--- net-2.6.19.orig/net/core/neighbour.c
+++ net-2.6.19/net/core/neighbour.c
@@ -455,6 +455,7 @@ struct pneigh_entry * pneigh_lookup(stru
 				    struct net_device *dev, int creat)
 {
 	struct pneigh_entry *n;
+	struct hlist_node *tmp;
 	int key_len = tbl->key_len;
 	u32 hash_val = *(u32 *)(pkey + key_len - 4);
 
@@ -465,7 +466,7 @@ struct pneigh_entry * pneigh_lookup(stru
 
 	read_lock_bh(&tbl->lock);
 
-	for (n = tbl->phash_buckets[hash_val]; n; n = n->next) {
+	hlist_for_each_entry(n, tmp, &tbl->phash_buckets[hash_val], hlist) {
 		if (!memcmp(n->key, pkey, key_len) &&
 		    (n->dev == dev || !n->dev)) {
 			read_unlock_bh(&tbl->lock);
@@ -495,8 +496,7 @@ struct pneigh_entry * pneigh_lookup(stru
 	}
 
 	write_lock_bh(&tbl->lock);
-	n->next = tbl->phash_buckets[hash_val];
-	tbl->phash_buckets[hash_val] = n;
+	hlist_add_head(&n->hlist, &tbl->phash_buckets[hash_val]);
 	write_unlock_bh(&tbl->lock);
 out:
 	return n;
@@ -506,7 +506,8 @@ out:
 int pneigh_delete(struct neigh_table *tbl, const void *pkey,
 		  struct net_device *dev)
 {
-	struct pneigh_entry *n, **np;
+	struct pneigh_entry *n;
+	struct hlist_node *tmp;
 	int key_len = tbl->key_len;
 	u32 hash_val = *(u32 *)(pkey + key_len - 4);
 
@@ -516,10 +517,9 @@ int pneigh_delete(struct neigh_table *tb
 	hash_val &= PNEIGH_HASHMASK;
 
 	write_lock_bh(&tbl->lock);
-	for (np = &tbl->phash_buckets[hash_val]; (n = *np) != NULL;
-	     np = &n->next) {
+	hlist_for_each_entry(n, tmp, &tbl->phash_buckets[hash_val], hlist) {
 		if (!memcmp(n->key, pkey, key_len) && n->dev == dev) {
-			*np = n->next;
+			hlist_del(&n->hlist);
 			write_unlock_bh(&tbl->lock);
 			if (tbl->pdestructor)
 				tbl->pdestructor(n);
@@ -535,22 +535,21 @@ int pneigh_delete(struct neigh_table *tb
 
 static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
 {
-	struct pneigh_entry *n, **np;
 	u32 h;
 
 	for (h = 0; h <= PNEIGH_HASHMASK; h++) {
-		np = &tbl->phash_buckets[h];
-		while ((n = *np) != NULL) {
+		struct pneigh_entry *n;
+		struct hlist_node *tmp, *nxt;
+
+		hlist_for_each_entry_safe(n, tmp, nxt, &tbl->phash_buckets[h], hlist) {
 			if (!dev || n->dev == dev) {
-				*np = n->next;
+				hlist_del(&n->hlist);
 				if (tbl->pdestructor)
 					tbl->pdestructor(n);
 				if (n->dev)
 					dev_put(n->dev);
 				kfree(n);
-				continue;
 			}
-			np = &n->next;
 		}
 	}
 	return -ENOENT;
@@ -1332,7 +1331,6 @@ void neigh_parms_destroy(struct neigh_pa
 void neigh_table_init_no_netlink(struct neigh_table *tbl)
 {
 	unsigned long now = jiffies;
-	unsigned long phsize;
 
 	atomic_set(&tbl->parms.refcnt, 1);
 	INIT_RCU_HEAD(&tbl->parms.rcu_head);
@@ -1363,8 +1361,8 @@ void neigh_table_init_no_netlink(struct 
 	tbl->hash_mask = 1;
 	tbl->hash_buckets = neigh_hash_alloc(tbl->hash_mask + 1);
 
-	phsize = (PNEIGH_HASHMASK + 1) * sizeof(struct pneigh_entry *);
-	tbl->phash_buckets = kzalloc(phsize, GFP_KERNEL);
+	tbl->phash_buckets = kcalloc(PNEIGH_HASHMASK + 1, sizeof(struct hlist_head),
+				     GFP_KERNEL);
 
 	if (!tbl->hash_buckets || !tbl->phash_buckets)
 		panic("cannot allocate neighbour cache hashes");
@@ -2192,18 +2190,18 @@ static struct pneigh_entry *pneigh_get_f
 {
 	struct neigh_seq_state *state = seq->private;
 	struct neigh_table *tbl = state->tbl;
-	struct pneigh_entry *pn = NULL;
+	struct hlist_node *pn = NULL;
 	int bucket = state->bucket;
 
 	state->flags |= NEIGH_SEQ_IS_PNEIGH;
 	for (bucket = 0; bucket <= PNEIGH_HASHMASK; bucket++) {
-		pn = tbl->phash_buckets[bucket];
+		pn = tbl->phash_buckets[bucket].first;
 		if (pn)
 			break;
 	}
 	state->bucket = bucket;
 
-	return pn;
+	return pn ? hlist_entry(pn, struct pneigh_entry, hlist) : NULL;
 }
 
 static struct pneigh_entry *pneigh_get_next(struct seq_file *seq,
@@ -2212,20 +2210,24 @@ static struct pneigh_entry *pneigh_get_n
 {
 	struct neigh_seq_state *state = seq->private;
 	struct neigh_table *tbl = state->tbl;
+	struct hlist_node *tmp = &pn->hlist;
 
-	pn = pn->next;
-	while (!pn) {
-		if (++state->bucket > PNEIGH_HASHMASK)
-			break;
-		pn = tbl->phash_buckets[state->bucket];
-		if (pn)
-			break;
+	tmp = tmp->next;
+	if (tmp)
+		goto found;
+
+	while (++state->bucket < PNEIGH_HASHMASK) {
+		tmp = tbl->phash_buckets[state->bucket].first;
+		if (tmp)
+			goto found;
 	}
+	return NULL;
 
-	if (pn && pos)
+found:
+	if (pos)
 		--(*pos);
 
-	return pn;
+	return hlist_entry(tmp, struct pneigh_entry, hlist);
 }
 
 static struct pneigh_entry *pneigh_get_idx(struct seq_file *seq, loff_t *pos)

--


  parent reply	other threads:[~2006-08-14 21:24 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-08-14 21:20 [RFC 0/7] neighbour table lockless read Stephen Hemminger
2006-08-14 21:20 ` [RFC 1/7] net neighbor: convert top level list to RCU Stephen Hemminger
2006-08-14 21:20 ` [RFC 2/7] neighbour: convert neighbour hash table to hlist Stephen Hemminger
2006-08-14 21:20 ` Stephen Hemminger [this message]
2006-08-14 21:20 ` [RFC 4/7] net neighbour: convert to RCU Stephen Hemminger
2006-08-14 21:20 ` [RFC 5/7] neighbour: convert lookup to sequence lock Stephen Hemminger
2006-08-14 22:22   ` Thomas Graf
2006-08-14 22:37     ` Stephen Hemminger
2006-08-14 23:17       ` Thomas Graf
2006-08-15  0:42         ` Alexey Kuznetsov
2006-08-14 21:20 ` [RFC 6/7] neighbour: convert hard header cache to sequence number Stephen Hemminger
2006-08-14 21:20 ` [RFC 7/7] neighbour: reduce exports Stephen Hemminger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060814212143.416542832@localhost.localdomain \
    --to=shemminger@osdl.org \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).