Commit 06801916 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by David S. Miller

[IPV4] fib_trie: cleanup

Try this out:
     * replace macro's with inlines
     * get rid of places doing multiple evaluations of NODE_PARENT

[akpm@linux-foundation.org: rcu_dereference wants an lval]
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 13dae426
...@@ -93,15 +93,8 @@ typedef unsigned int t_key; ...@@ -93,15 +93,8 @@ typedef unsigned int t_key;
#define T_TNODE 0 #define T_TNODE 0
#define T_LEAF 1 #define T_LEAF 1
#define NODE_TYPE_MASK 0x1UL #define NODE_TYPE_MASK 0x1UL
#define NODE_PARENT(node) \
((struct tnode *)rcu_dereference(((node)->parent & ~NODE_TYPE_MASK)))
#define NODE_TYPE(node) ((node)->parent & NODE_TYPE_MASK) #define NODE_TYPE(node) ((node)->parent & NODE_TYPE_MASK)
#define NODE_SET_PARENT(node, ptr) \
rcu_assign_pointer((node)->parent, \
((unsigned long)(ptr)) | NODE_TYPE(node))
#define IS_TNODE(n) (!(n->parent & T_LEAF)) #define IS_TNODE(n) (!(n->parent & T_LEAF))
#define IS_LEAF(n) (n->parent & T_LEAF) #define IS_LEAF(n) (n->parent & T_LEAF)
...@@ -174,6 +167,19 @@ static void tnode_free(struct tnode *tn); ...@@ -174,6 +167,19 @@ static void tnode_free(struct tnode *tn);
static struct kmem_cache *fn_alias_kmem __read_mostly; static struct kmem_cache *fn_alias_kmem __read_mostly;
static struct trie *trie_local = NULL, *trie_main = NULL; static struct trie *trie_local = NULL, *trie_main = NULL;
static inline struct tnode *node_parent(struct node *node)
{
struct tnode *ret;
ret = (struct tnode *)(node->parent & ~NODE_TYPE_MASK);
return rcu_dereference(ret);
}
static inline void node_set_parent(struct node *node, struct tnode *ptr)
{
rcu_assign_pointer(node->parent,
(unsigned long)ptr | NODE_TYPE(node));
}
/* rcu_read_lock needs to be hold by caller from readside */ /* rcu_read_lock needs to be hold by caller from readside */
...@@ -446,7 +452,7 @@ static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int w ...@@ -446,7 +452,7 @@ static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int w
tn->full_children++; tn->full_children++;
if (n) if (n)
NODE_SET_PARENT(n, tn); node_set_parent(n, tn);
rcu_assign_pointer(tn->child[i], n); rcu_assign_pointer(tn->child[i], n);
} }
...@@ -481,7 +487,7 @@ static struct node *resize(struct trie *t, struct tnode *tn) ...@@ -481,7 +487,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
continue; continue;
/* compress one level */ /* compress one level */
NODE_SET_PARENT(n, NULL); node_set_parent(n, NULL);
tnode_free(tn); tnode_free(tn);
return n; return n;
} }
...@@ -636,7 +642,7 @@ static struct node *resize(struct trie *t, struct tnode *tn) ...@@ -636,7 +642,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
/* compress one level */ /* compress one level */
NODE_SET_PARENT(n, NULL); node_set_parent(n, NULL);
tnode_free(tn); tnode_free(tn);
return n; return n;
} }
...@@ -961,24 +967,21 @@ fib_find_node(struct trie *t, u32 key) ...@@ -961,24 +967,21 @@ fib_find_node(struct trie *t, u32 key)
static struct node *trie_rebalance(struct trie *t, struct tnode *tn) static struct node *trie_rebalance(struct trie *t, struct tnode *tn)
{ {
int wasfull; int wasfull;
t_key cindex, key; t_key cindex, key = tn->key;
struct tnode *tp = NULL; struct tnode *tp;
key = tn->key;
while (tn != NULL && NODE_PARENT(tn) != NULL) { while (tn != NULL && (tp = node_parent((struct node *)tn)) != NULL) {
tp = NODE_PARENT(tn);
cindex = tkey_extract_bits(key, tp->pos, tp->bits); cindex = tkey_extract_bits(key, tp->pos, tp->bits);
wasfull = tnode_full(tp, tnode_get_child(tp, cindex)); wasfull = tnode_full(tp, tnode_get_child(tp, cindex));
tn = (struct tnode *) resize (t, (struct tnode *)tn); tn = (struct tnode *) resize (t, (struct tnode *)tn);
tnode_put_child_reorg((struct tnode *)tp, cindex,(struct node*)tn, wasfull); tnode_put_child_reorg((struct tnode *)tp, cindex,(struct node*)tn, wasfull);
if (!NODE_PARENT(tn)) tp = node_parent((struct node *) tn);
if (!tp)
break; break;
tn = tp;
tn = NODE_PARENT(tn);
} }
/* Handle last (top) tnode */ /* Handle last (top) tnode */
if (IS_TNODE(tn)) if (IS_TNODE(tn))
tn = (struct tnode*) resize(t, (struct tnode *)tn); tn = (struct tnode*) resize(t, (struct tnode *)tn);
...@@ -1031,7 +1034,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen) ...@@ -1031,7 +1034,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
pos = tn->pos + tn->bits; pos = tn->pos + tn->bits;
n = tnode_get_child(tn, tkey_extract_bits(key, tn->pos, tn->bits)); n = tnode_get_child(tn, tkey_extract_bits(key, tn->pos, tn->bits));
BUG_ON(n && NODE_PARENT(n) != tn); BUG_ON(n && node_parent(n) != tn);
} else } else
break; break;
} }
...@@ -1083,7 +1086,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen) ...@@ -1083,7 +1086,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
if (t->trie && n == NULL) { if (t->trie && n == NULL) {
/* Case 2: n is NULL, and will just insert a new leaf */ /* Case 2: n is NULL, and will just insert a new leaf */
NODE_SET_PARENT(l, tp); node_set_parent((struct node *)l, tp);
cindex = tkey_extract_bits(key, tp->pos, tp->bits); cindex = tkey_extract_bits(key, tp->pos, tp->bits);
put_child(t, (struct tnode *)tp, cindex, (struct node *)l); put_child(t, (struct tnode *)tp, cindex, (struct node *)l);
...@@ -1114,7 +1117,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen) ...@@ -1114,7 +1117,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
goto err; goto err;
} }
NODE_SET_PARENT(tn, tp); node_set_parent((struct node *)tn, tp);
missbit = tkey_extract_bits(key, newpos, 1); missbit = tkey_extract_bits(key, newpos, 1);
put_child(t, tn, missbit, (struct node *)l); put_child(t, tn, missbit, (struct node *)l);
...@@ -1495,12 +1498,13 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result ...@@ -1495,12 +1498,13 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
if (chopped_off <= pn->bits) { if (chopped_off <= pn->bits) {
cindex &= ~(1 << (chopped_off-1)); cindex &= ~(1 << (chopped_off-1));
} else { } else {
if (NODE_PARENT(pn) == NULL) struct tnode *parent = node_parent((struct node *) pn);
if (!parent)
goto failed; goto failed;
/* Get Child's index */ /* Get Child's index */
cindex = tkey_extract_bits(pn->key, NODE_PARENT(pn)->pos, NODE_PARENT(pn)->bits); cindex = tkey_extract_bits(pn->key, parent->pos, parent->bits);
pn = NODE_PARENT(pn); pn = parent;
chopped_off = 0; chopped_off = 0;
#ifdef CONFIG_IP_FIB_TRIE_STATS #ifdef CONFIG_IP_FIB_TRIE_STATS
...@@ -1536,7 +1540,7 @@ static int trie_leaf_remove(struct trie *t, t_key key) ...@@ -1536,7 +1540,7 @@ static int trie_leaf_remove(struct trie *t, t_key key)
check_tnode(tn); check_tnode(tn);
n = tnode_get_child(tn ,tkey_extract_bits(key, tn->pos, tn->bits)); n = tnode_get_child(tn ,tkey_extract_bits(key, tn->pos, tn->bits));
BUG_ON(n && NODE_PARENT(n) != tn); BUG_ON(n && node_parent(n) != tn);
} }
l = (struct leaf *) n; l = (struct leaf *) n;
...@@ -1551,7 +1555,7 @@ static int trie_leaf_remove(struct trie *t, t_key key) ...@@ -1551,7 +1555,7 @@ static int trie_leaf_remove(struct trie *t, t_key key)
t->revision++; t->revision++;
t->size--; t->size--;
tp = NODE_PARENT(n); tp = node_parent(n);
tnode_free((struct tnode *) n); tnode_free((struct tnode *) n);
if (tp) { if (tp) {
...@@ -1703,7 +1707,7 @@ static struct leaf *nextleaf(struct trie *t, struct leaf *thisleaf) ...@@ -1703,7 +1707,7 @@ static struct leaf *nextleaf(struct trie *t, struct leaf *thisleaf)
p = (struct tnode*) trie; /* Start */ p = (struct tnode*) trie; /* Start */
} else } else
p = (struct tnode *) NODE_PARENT(c); p = node_parent(c);
while (p) { while (p) {
int pos, last; int pos, last;
...@@ -1740,7 +1744,7 @@ static struct leaf *nextleaf(struct trie *t, struct leaf *thisleaf) ...@@ -1740,7 +1744,7 @@ static struct leaf *nextleaf(struct trie *t, struct leaf *thisleaf)
up: up:
/* No more children go up one step */ /* No more children go up one step */
c = (struct node *) p; c = (struct node *) p;
p = (struct tnode *) NODE_PARENT(p); p = node_parent(c);
} }
return NULL; /* Ready. Root of trie */ return NULL; /* Ready. Root of trie */
} }
...@@ -2043,7 +2047,7 @@ static struct node *fib_trie_get_next(struct fib_trie_iter *iter) ...@@ -2043,7 +2047,7 @@ static struct node *fib_trie_get_next(struct fib_trie_iter *iter)
} }
/* Current node exhausted, pop back up */ /* Current node exhausted, pop back up */
p = NODE_PARENT(tn); p = node_parent((struct node *)tn);
if (p) { if (p) {
cindex = tkey_extract_bits(tn->key, p->pos, p->bits)+1; cindex = tkey_extract_bits(tn->key, p->pos, p->bits)+1;
tn = p; tn = p;
...@@ -2317,7 +2321,7 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v) ...@@ -2317,7 +2321,7 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
if (v == SEQ_START_TOKEN) if (v == SEQ_START_TOKEN)
return 0; return 0;
if (!NODE_PARENT(n)) { if (!node_parent(n)) {
if (iter->trie == trie_local) if (iter->trie == trie_local)
seq_puts(seq, "<local>:\n"); seq_puts(seq, "<local>:\n");
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment