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

[IPV4] fib_trie: avoid extra search on delete

Get rid of extra search that made route deletion O(n).
Signed-off-by: default avatarStephen Hemminger <shemminger@vyatta.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a88ee229
...@@ -1545,49 +1545,23 @@ static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, ...@@ -1545,49 +1545,23 @@ static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp,
return ret; return ret;
} }
/* only called from updater side */ /*
static int trie_leaf_remove(struct trie *t, t_key key) * Remove the leaf and return parent.
*/
static void trie_leaf_remove(struct trie *t, struct leaf *l)
{ {
t_key cindex; struct tnode *tp = node_parent((struct node *) l);
struct tnode *tp = NULL;
struct node *n = t->trie;
struct leaf *l;
pr_debug("entering trie_leaf_remove(%p)\n", n);
/* Note that in the case skipped bits, those bits are *not* checked! pr_debug("entering trie_leaf_remove(%p)\n", l);
* When we finish this, we will have NULL or a T_LEAF, and the
* T_LEAF may or may not match our key.
*/
while (n != NULL && IS_TNODE(n)) {
struct tnode *tn = (struct tnode *) n;
check_tnode(tn);
n = tnode_get_child(tn, tkey_extract_bits(key,
tn->pos, tn->bits));
BUG_ON(n && node_parent(n) != tn);
}
l = (struct leaf *) n;
if (!n || !tkey_equals(l->key, key))
return 0;
/*
* Key found.
* Remove the leaf and rebalance the tree
*/
tp = node_parent(n);
tnode_free((struct tnode *) n);
if (tp) { if (tp) {
cindex = tkey_extract_bits(key, tp->pos, tp->bits); t_key cindex = tkey_extract_bits(l->key, tp->pos, tp->bits);
put_child(t, (struct tnode *)tp, cindex, NULL); put_child(t, (struct tnode *)tp, cindex, NULL);
rcu_assign_pointer(t->trie, trie_rebalance(t, tp)); rcu_assign_pointer(t->trie, trie_rebalance(t, tp));
} else } else
rcu_assign_pointer(t->trie, NULL); rcu_assign_pointer(t->trie, NULL);
return 1; tnode_free((struct tnode *) l);
} }
/* /*
...@@ -1665,7 +1639,7 @@ static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg) ...@@ -1665,7 +1639,7 @@ static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg)
} }
if (hlist_empty(&l->list)) if (hlist_empty(&l->list))
trie_leaf_remove(t, key); trie_leaf_remove(t, l);
if (fa->fa_state & FA_S_ACCESSED) if (fa->fa_state & FA_S_ACCESSED)
rt_cache_flush(-1); rt_cache_flush(-1);
...@@ -1778,19 +1752,19 @@ static struct leaf *trie_nextleaf(struct leaf *l) ...@@ -1778,19 +1752,19 @@ static struct leaf *trie_nextleaf(struct leaf *l)
static int fn_trie_flush(struct fib_table *tb) static int fn_trie_flush(struct fib_table *tb)
{ {
struct trie *t = (struct trie *) tb->tb_data; struct trie *t = (struct trie *) tb->tb_data;
struct leaf *ll = NULL, *l = NULL; struct leaf *l, *ll = NULL;
int found = 0; int found = 0;
for (l = trie_firstleaf(t); l; l = trie_nextleaf(l)) { for (l = trie_firstleaf(t); l; l = trie_nextleaf(l)) {
found += trie_flush_leaf(t, l); found += trie_flush_leaf(t, l);
if (ll && hlist_empty(&ll->list)) if (ll && hlist_empty(&ll->list))
trie_leaf_remove(t, ll->key); trie_leaf_remove(t, ll);
ll = l; ll = l;
} }
if (ll && hlist_empty(&ll->list)) if (ll && hlist_empty(&ll->list))
trie_leaf_remove(t, ll->key); trie_leaf_remove(t, ll);
pr_debug("trie_flush found=%d\n", found); pr_debug("trie_flush found=%d\n", found);
return found; return found;
......
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