Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+36 −32
Original line number Original line Diff line number Diff line
@@ -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);
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
		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)
				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)


			/* 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)
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)
			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)
	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)
			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
		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)
		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)
	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)


		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)
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)
	}
	}


	/* 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)
	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