mirror of
https://github.com/adulau/aha.git
synced 2024-12-29 04:06:22 +00:00
[IPV4]: FIB trie cleanup
This is a redo of earlier cleanup stuff: * replace DBG() macro with pr_debug() * get rid of duplicate extern's that are already in fib_lookup.h * use BUG_ON and WARN_ON * don't use BUG checks for null pointers where next statement would get a fault anyway * remove debug printout when rebalance causes deep tree * remove trailing blanks Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Robert Olsson <robert.olsson@its.uu.se> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
331968bd0c
commit
0c7770c740
1 changed files with 31 additions and 69 deletions
|
@ -157,10 +157,6 @@ struct trie {
|
||||||
unsigned int revision;
|
unsigned int revision;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int trie_debug = 0;
|
|
||||||
|
|
||||||
#define DBG(x...) do { if (trie_debug) printk(x); } while (0)
|
|
||||||
|
|
||||||
static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n);
|
static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n);
|
||||||
static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull);
|
static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull);
|
||||||
static struct node *resize(struct trie *t, struct tnode *tn);
|
static struct node *resize(struct trie *t, struct tnode *tn);
|
||||||
|
@ -168,12 +164,6 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn);
|
||||||
static struct tnode *halve(struct trie *t, struct tnode *tn);
|
static struct tnode *halve(struct trie *t, struct tnode *tn);
|
||||||
static void tnode_free(struct tnode *tn);
|
static void tnode_free(struct tnode *tn);
|
||||||
static void trie_dump_seq(struct seq_file *seq, struct trie *t);
|
static void trie_dump_seq(struct seq_file *seq, struct trie *t);
|
||||||
extern struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio);
|
|
||||||
extern int fib_detect_death(struct fib_info *fi, int order,
|
|
||||||
struct fib_info **last_resort, int *last_idx, int *dflt);
|
|
||||||
|
|
||||||
extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa, int z, int tb_id,
|
|
||||||
struct nlmsghdr *n, struct netlink_skb_parms *req);
|
|
||||||
|
|
||||||
static kmem_cache_t *fn_alias_kmem;
|
static kmem_cache_t *fn_alias_kmem;
|
||||||
static struct trie *trie_local = NULL, *trie_main = NULL;
|
static struct trie *trie_local = NULL, *trie_main = NULL;
|
||||||
|
@ -294,11 +284,9 @@ static void fn_free_alias(struct fib_alias *fa)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void check_tnode(struct tnode *tn)
|
static inline void check_tnode(const struct tnode *tn)
|
||||||
{
|
{
|
||||||
if (tn && tn->pos+tn->bits > 32) {
|
WARN_ON(tn && tn->pos+tn->bits > 32);
|
||||||
printk("TNODE ERROR tn=%p, pos=%d, bits=%d\n", tn, tn->pos, tn->bits);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int halve_threshold = 25;
|
static int halve_threshold = 25;
|
||||||
|
@ -374,21 +362,19 @@ static struct tnode* tnode_new(t_key key, int pos, int bits)
|
||||||
tn->empty_children = 1<<bits;
|
tn->empty_children = 1<<bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG("AT %p s=%u %u\n", tn, (unsigned int) sizeof(struct tnode),
|
pr_debug("AT %p s=%u %u\n", tn, (unsigned int) sizeof(struct tnode),
|
||||||
(unsigned int) (sizeof(struct node) * 1<<bits));
|
(unsigned int) (sizeof(struct node) * 1<<bits));
|
||||||
return tn;
|
return tn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tnode_free(struct tnode *tn)
|
static void tnode_free(struct tnode *tn)
|
||||||
{
|
{
|
||||||
BUG_ON(!tn);
|
|
||||||
|
|
||||||
if (IS_LEAF(tn)) {
|
if (IS_LEAF(tn)) {
|
||||||
free_leaf((struct leaf *)tn);
|
free_leaf((struct leaf *)tn);
|
||||||
DBG("FL %p \n", tn);
|
pr_debug("FL %p \n", tn);
|
||||||
} else {
|
} else {
|
||||||
__tnode_free(tn);
|
__tnode_free(tn);
|
||||||
DBG("FT %p \n", tn);
|
pr_debug("FT %p \n", tn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,10 +406,8 @@ static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int w
|
||||||
struct node *chi;
|
struct node *chi;
|
||||||
int isfull;
|
int isfull;
|
||||||
|
|
||||||
if (i >= 1<<tn->bits) {
|
BUG_ON(i >= 1<<tn->bits);
|
||||||
printk("bits=%d, i=%d\n", tn->bits, i);
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
write_lock_bh(&fib_lock);
|
write_lock_bh(&fib_lock);
|
||||||
chi = tn->child[i];
|
chi = tn->child[i];
|
||||||
|
|
||||||
|
@ -459,8 +443,8 @@ static struct node *resize(struct trie *t, struct tnode *tn)
|
||||||
if (!tn)
|
if (!tn)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
DBG("In tnode_resize %p inflate_threshold=%d threshold=%d\n",
|
pr_debug("In tnode_resize %p inflate_threshold=%d threshold=%d\n",
|
||||||
tn, inflate_threshold, halve_threshold);
|
tn, inflate_threshold, halve_threshold);
|
||||||
|
|
||||||
/* No children */
|
/* No children */
|
||||||
if (tn->empty_children == tnode_child_length(tn)) {
|
if (tn->empty_children == tnode_child_length(tn)) {
|
||||||
|
@ -625,11 +609,11 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn)
|
||||||
int olen = tnode_child_length(tn);
|
int olen = tnode_child_length(tn);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DBG("In inflate\n");
|
pr_debug("In inflate\n");
|
||||||
|
|
||||||
tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits + 1);
|
tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits + 1);
|
||||||
|
|
||||||
if (!tn)
|
if (!tn)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -749,12 +733,12 @@ nomem:
|
||||||
int size = tnode_child_length(tn);
|
int size = tnode_child_length(tn);
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for(j = 0; j < size; j++)
|
for (j = 0; j < size; j++)
|
||||||
if (tn->child[j])
|
if (tn->child[j])
|
||||||
tnode_free((struct tnode *)tn->child[j]);
|
tnode_free((struct tnode *)tn->child[j]);
|
||||||
|
|
||||||
tnode_free(tn);
|
tnode_free(tn);
|
||||||
|
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -766,7 +750,7 @@ static struct tnode *halve(struct trie *t, struct tnode *tn)
|
||||||
int i;
|
int i;
|
||||||
int olen = tnode_child_length(tn);
|
int olen = tnode_child_length(tn);
|
||||||
|
|
||||||
DBG("In halve\n");
|
pr_debug("In halve\n");
|
||||||
|
|
||||||
tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits - 1);
|
tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits - 1);
|
||||||
|
|
||||||
|
@ -785,14 +769,14 @@ static struct tnode *halve(struct trie *t, struct tnode *tn)
|
||||||
right = tnode_get_child(oldtnode, i+1);
|
right = tnode_get_child(oldtnode, i+1);
|
||||||
|
|
||||||
/* Two nonempty children */
|
/* Two nonempty children */
|
||||||
if (left && right) {
|
if (left && right) {
|
||||||
struct tnode *newn;
|
struct tnode *newn;
|
||||||
|
|
||||||
newn = tnode_new(left->key, tn->pos + tn->bits, 1);
|
newn = tnode_new(left->key, tn->pos + tn->bits, 1);
|
||||||
|
|
||||||
if (!newn)
|
if (!newn)
|
||||||
goto nomem;
|
goto nomem;
|
||||||
|
|
||||||
put_child(t, tn, i/2, (struct node *)newn);
|
put_child(t, tn, i/2, (struct node *)newn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -810,7 +794,7 @@ static struct tnode *halve(struct trie *t, struct tnode *tn)
|
||||||
continue;
|
continue;
|
||||||
put_child(t, tn, i/2, right);
|
put_child(t, tn, i/2, right);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (right == NULL) {
|
if (right == NULL) {
|
||||||
put_child(t, tn, i/2, left);
|
put_child(t, tn, i/2, left);
|
||||||
|
@ -820,9 +804,6 @@ static struct tnode *halve(struct trie *t, struct tnode *tn)
|
||||||
/* Two nonempty children */
|
/* Two nonempty children */
|
||||||
newBinNode = (struct tnode *) tnode_get_child(tn, i/2);
|
newBinNode = (struct tnode *) tnode_get_child(tn, i/2);
|
||||||
put_child(t, tn, i/2, NULL);
|
put_child(t, tn, i/2, NULL);
|
||||||
|
|
||||||
BUG_ON(!newBinNode);
|
|
||||||
|
|
||||||
put_child(t, newBinNode, 0, left);
|
put_child(t, newBinNode, 0, left);
|
||||||
put_child(t, newBinNode, 1, right);
|
put_child(t, newBinNode, 1, right);
|
||||||
put_child(t, tn, i/2, resize(t, newBinNode));
|
put_child(t, tn, i/2, resize(t, newBinNode));
|
||||||
|
@ -834,12 +815,12 @@ nomem:
|
||||||
int size = tnode_child_length(tn);
|
int size = tnode_child_length(tn);
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for(j = 0; j < size; j++)
|
for (j = 0; j < size; j++)
|
||||||
if (tn->child[j])
|
if (tn->child[j])
|
||||||
tnode_free((struct tnode *)tn->child[j]);
|
tnode_free((struct tnode *)tn->child[j]);
|
||||||
|
|
||||||
tnode_free(tn);
|
tnode_free(tn);
|
||||||
|
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -939,22 +920,10 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn)
|
||||||
t_key cindex, key;
|
t_key cindex, key;
|
||||||
struct tnode *tp = NULL;
|
struct tnode *tp = NULL;
|
||||||
|
|
||||||
BUG_ON(!tn);
|
|
||||||
|
|
||||||
key = tn->key;
|
key = tn->key;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
while (tn != NULL && NODE_PARENT(tn) != NULL) {
|
while (tn != NULL && NODE_PARENT(tn) != NULL) {
|
||||||
if (i > 10) {
|
|
||||||
printk("Rebalance tn=%p \n", tn);
|
|
||||||
if (tn)
|
|
||||||
printk("tn->parent=%p \n", NODE_PARENT(tn));
|
|
||||||
|
|
||||||
printk("Rebalance tp=%p \n", tp);
|
|
||||||
if (tp)
|
|
||||||
printk("tp->parent=%p \n", NODE_PARENT(tp));
|
|
||||||
}
|
|
||||||
|
|
||||||
BUG_ON(i > 12); /* Why is this a bug? -ojn */
|
BUG_ON(i > 12); /* Why is this a bug? -ojn */
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
@ -1019,10 +988,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));
|
||||||
|
|
||||||
if (n && NODE_PARENT(n) != tn) {
|
BUG_ON(n && NODE_PARENT(n) != tn);
|
||||||
printk("BUG tn=%p, n->parent=%p\n", tn, NODE_PARENT(n));
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1076,8 +1042,6 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
|
||||||
|
|
||||||
NODE_SET_PARENT(l, tp);
|
NODE_SET_PARENT(l, tp);
|
||||||
|
|
||||||
BUG_ON(!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);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1158,7 +1122,7 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
|
||||||
|
|
||||||
key = ntohl(key);
|
key = ntohl(key);
|
||||||
|
|
||||||
DBG("Insert table=%d %08x/%d\n", tb->tb_id, key, plen);
|
pr_debug("Insert table=%d %08x/%d\n", tb->tb_id, key, plen);
|
||||||
|
|
||||||
mask = ntohl(inet_make_mask(plen));
|
mask = ntohl(inet_make_mask(plen));
|
||||||
|
|
||||||
|
@ -1282,7 +1246,8 @@ err:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int check_leaf(struct trie *t, struct leaf *l, t_key key, int *plen, const struct flowi *flp,
|
static inline int check_leaf(struct trie *t, struct leaf *l,
|
||||||
|
t_key key, int *plen, const struct flowi *flp,
|
||||||
struct fib_result *res)
|
struct fib_result *res)
|
||||||
{
|
{
|
||||||
int err, i;
|
int err, i;
|
||||||
|
@ -1511,7 +1476,7 @@ static int trie_leaf_remove(struct trie *t, t_key key)
|
||||||
struct node *n = t->trie;
|
struct node *n = t->trie;
|
||||||
struct leaf *l;
|
struct leaf *l;
|
||||||
|
|
||||||
DBG("entering trie_leaf_remove(%p)\n", n);
|
pr_debug("entering trie_leaf_remove(%p)\n", n);
|
||||||
|
|
||||||
/* Note that in the case skipped bits, those bits are *not* checked!
|
/* Note that in the case skipped bits, those bits are *not* checked!
|
||||||
* When we finish this, we will have NULL or a T_LEAF, and the
|
* When we finish this, we will have NULL or a T_LEAF, and the
|
||||||
|
@ -1523,10 +1488,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));
|
||||||
|
|
||||||
if (n && NODE_PARENT(n) != tn) {
|
BUG_ON(n && NODE_PARENT(n) != tn);
|
||||||
printk("BUG tn=%p, n->parent=%p\n", tn, NODE_PARENT(n));
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
l = (struct leaf *) n;
|
l = (struct leaf *) n;
|
||||||
|
|
||||||
|
@ -1594,7 +1556,7 @@ fn_trie_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
|
||||||
if (!fa)
|
if (!fa)
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
|
|
||||||
DBG("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t);
|
pr_debug("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t);
|
||||||
|
|
||||||
fa_to_delete = NULL;
|
fa_to_delete = NULL;
|
||||||
fa_head = fa->fa_list.prev;
|
fa_head = fa->fa_list.prev;
|
||||||
|
@ -1762,7 +1724,7 @@ static int fn_trie_flush(struct fib_table *tb)
|
||||||
if (ll && hlist_empty(&ll->list))
|
if (ll && hlist_empty(&ll->list))
|
||||||
trie_leaf_remove(t, ll->key);
|
trie_leaf_remove(t, ll->key);
|
||||||
|
|
||||||
DBG("trie_flush found=%d\n", found);
|
pr_debug("trie_flush found=%d\n", found);
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue