]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/fib_trie.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge
[linux-2.6-omap-h63xx.git] / net / ipv4 / fib_trie.c
index e320b32373e5703edac6e7b7f9e2c3310100cd1b..95a639f2e3dbc654df393c3f985b20c4fa036560 100644 (file)
@@ -50,7 +50,7 @@
  *             Patrick McHardy <kaber@trash.net>
  */
 
-#define VERSION "0.404"
+#define VERSION "0.407"
 
 #include <linux/config.h>
 #include <asm/uaccess.h>
@@ -84,7 +84,7 @@
 #include "fib_lookup.h"
 
 #undef CONFIG_IP_FIB_TRIE_STATS
-#define MAX_CHILDS 16384
+#define MAX_STAT_DEPTH 32
 
 #define KEYLENGTH (8*sizeof(t_key))
 #define MASK_PFX(k, l) (((l)==0)?0:(k >> (KEYLENGTH-l)) << (KEYLENGTH-l))
@@ -154,7 +154,7 @@ struct trie_stat {
        unsigned int tnodes;
        unsigned int leaves;
        unsigned int nullpointers;
-       unsigned int nodesizes[MAX_CHILDS];
+       unsigned int nodesizes[MAX_STAT_DEPTH];
 };
 
 struct trie {
@@ -314,11 +314,6 @@ static void __leaf_free_rcu(struct rcu_head *head)
        kfree(container_of(head, struct leaf, rcu));
 }
 
-static inline void free_leaf(struct leaf *leaf)
-{
-       call_rcu(&leaf->rcu, __leaf_free_rcu);
-}
-
 static void __leaf_info_free_rcu(struct rcu_head *head)
 {
        kfree(container_of(head, struct leaf_info, rcu));
@@ -357,7 +352,12 @@ static void __tnode_free_rcu(struct rcu_head *head)
 
 static inline void tnode_free(struct tnode *tn)
 {
-       call_rcu(&tn->rcu, __tnode_free_rcu);
+       if(IS_LEAF(tn)) {
+               struct leaf *l = (struct leaf *) tn;
+               call_rcu_bh(&l->rcu, __leaf_free_rcu);
+       }
+        else
+               call_rcu(&tn->rcu, __tnode_free_rcu);
 }
 
 static struct leaf *leaf_new(void)
@@ -2040,7 +2040,15 @@ rescan:
 static struct node *fib_trie_get_first(struct fib_trie_iter *iter,
                                       struct trie *t)
 {
-       struct node *n = rcu_dereference(t->trie);
+       struct node *n ;
+
+       if(!t)
+               return NULL;
+
+       n = rcu_dereference(t->trie);
+
+       if(!iter)
+               return NULL;
 
        if (n && IS_TNODE(n)) {
                iter->tnode = (struct tnode *) n;
@@ -2072,7 +2080,9 @@ static void trie_collect_stats(struct trie *t, struct trie_stat *s)
                        int i;
 
                        s->tnodes++;
-                       s->nodesizes[tn->bits]++;
+                       if(tn->bits < MAX_STAT_DEPTH)
+                               s->nodesizes[tn->bits]++;
+
                        for (i = 0; i < (1<<tn->bits); i++)
                                if (!tn->child[i])
                                        s->nullpointers++;
@@ -2102,8 +2112,8 @@ static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat)
        seq_printf(seq, "\tInternal nodes: %d\n\t", stat->tnodes);
        bytes += sizeof(struct tnode) * stat->tnodes;
 
-       max = MAX_CHILDS-1;
-       while (max >= 0 && stat->nodesizes[max] == 0)
+       max = MAX_STAT_DEPTH;
+       while (max > 0 && stat->nodesizes[max-1] == 0)
                max--;
 
        pointers = 0;