Stephen Hemminger writes: > This is how I did it:
Yes looks like an elegant solution. Did you even test it? Maybe we see some effects in just dumping a full table? Anyway lookup should be tested in some way. We can a lot of analyzing before getting to right entry, local_table backtracking, main lookup w. ev. backtracking etc. So hopefully we get paid for this work. Also it might be idea to do some analysis of the fib_aliases list. Maybe the trick can be done again? ;) Cheers --ro > --- a/net/ipv4/fib_trie.c 2008-01-15 09:14:53.000000000 -0800 > +++ b/net/ipv4/fib_trie.c 2008-01-15 09:21:48.000000000 -0800 > @@ -101,13 +101,6 @@ struct node { > t_key key; > }; > > -struct leaf { > - unsigned long parent; > - t_key key; > - struct hlist_head list; > - struct rcu_head rcu; > -}; > - > struct leaf_info { > struct hlist_node hlist; > struct rcu_head rcu; > @@ -115,6 +108,13 @@ struct leaf_info { > struct list_head falh; > }; > > +struct leaf { > + unsigned long parent; > + t_key key; > + struct hlist_head list; > + struct rcu_head rcu; > +}; > + > struct tnode { > unsigned long parent; > t_key key; > @@ -321,16 +321,6 @@ static void __leaf_free_rcu(struct rcu_h > kmem_cache_free(trie_leaf_kmem, leaf); > } > > -static void __leaf_info_free_rcu(struct rcu_head *head) > -{ > - kfree(container_of(head, struct leaf_info, rcu)); > -} > - > -static inline void free_leaf_info(struct leaf_info *leaf) > -{ > - call_rcu(&leaf->rcu, __leaf_info_free_rcu); > -} > - > static struct tnode *tnode_alloc(size_t size) > { > struct page *pages; > @@ -357,7 +347,7 @@ static void __tnode_free_rcu(struct rcu_ > free_pages((unsigned long)tn, get_order(size)); > } > > -static inline void tnode_free(struct tnode *tn) > +static void tnode_free(struct tnode *tn) > { > if (IS_LEAF(tn)) { > struct leaf *l = (struct leaf *) tn; > @@ -376,16 +366,41 @@ static struct leaf *leaf_new(void) > return l; > } > > +static void leaf_info_init(struct leaf_info *li, int plen) > +{ > + li->plen = plen; > + INIT_LIST_HEAD(&li->falh); > +} > + > +static struct leaf_info *leaf_info_first(struct leaf *l, int plen) > +{ > + struct leaf_info *li = (struct leaf_info *) (l + 1); > + leaf_info_init(li, plen); > + return li; > +} > + > static struct leaf_info *leaf_info_new(int plen) > { > struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL); > - if (li) { > - li->plen = plen; > - INIT_LIST_HEAD(&li->falh); > - } > + if (li) > + leaf_info_init(li, plen); > + > return li; > } > > +static void __leaf_info_free_rcu(struct rcu_head *head) > +{ > + kfree(container_of(head, struct leaf_info, rcu)); > +} > + > +static inline void free_leaf_info(struct leaf *l, struct leaf_info *leaf) > +{ > + if (leaf == (struct leaf_info *)(l + 1)) > + return; > + > + call_rcu(&leaf->rcu, __leaf_info_free_rcu); > +} > + > static struct tnode* tnode_new(t_key key, int pos, int bits) > { > size_t sz = sizeof(struct tnode) + (sizeof(struct node *) << bits); > @@ -1047,18 +1062,13 @@ static struct list_head *fib_insert_node > insert_leaf_info(&l->list, li); > goto done; > } > - l = leaf_new(); > > + l = leaf_new(); > if (!l) > return NULL; > > l->key = key; > - li = leaf_info_new(plen); > - > - if (!li) { > - tnode_free((struct tnode *) l); > - return NULL; > - } > + li = leaf_info_first(l, plen); > > fa_head = &li->falh; > insert_leaf_info(&l->list, li); > @@ -1091,7 +1101,7 @@ static struct list_head *fib_insert_node > } > > if (!tn) { > - free_leaf_info(li); > + free_leaf_info(l, li); > tnode_free((struct tnode *) l); > return NULL; > } > @@ -1624,7 +1634,7 @@ static int fn_trie_delete(struct fib_tab > > if (list_empty(fa_head)) { > hlist_del_rcu(&li->hlist); > - free_leaf_info(li); > + free_leaf_info(l, li); > } > > if (hlist_empty(&l->list)) > @@ -1668,7 +1678,7 @@ static int trie_flush_leaf(struct trie * > > if (list_empty(&li->falh)) { > hlist_del_rcu(&li->hlist); > - free_leaf_info(li); > + free_leaf_info(l, li); > } > } > return found; > @@ -1935,7 +1945,8 @@ void __init fib_hash_init(void) > fn_alias_kmem = kmem_cache_create("ip_fib_alias", sizeof(struct > fib_alias), > 0, SLAB_PANIC, NULL); > > - trie_leaf_kmem = kmem_cache_create("ip_fib_trie", sizeof(struct leaf), > + trie_leaf_kmem = kmem_cache_create("ip_fib_trie", > + sizeof(struct leaf) + sizeof(struct > leaf_info), > 0, SLAB_PANIC, NULL); > } > -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html