[IPV4] fib_trie: size and statistics
authorStephen Hemminger <stephen.hemminger@vyatta.com>
Tue, 15 Jan 2008 07:11:54 +0000 (23:11 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 28 Jan 2008 23:02:14 +0000 (15:02 -0800)
Show number of entries in trie, the size field was being set but never used,
but it only counted leaves, not all entries. Refactor the two cases in
fib_triestat_seq_show into a single routine.

Note: the stat structure was being malloc'd but the stack usage isn't so
high (288 bytes) that it is worth the additional complexity.

Signed-off-by: Stephen Hemminger <stephen.hemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/fib_trie.c

index 72c78c2209d55acde507b44541aeaf2c371f66c5..a15cb0d2e113e6ce9181a1a274b6a65b3517234c 100644 (file)
@@ -148,10 +148,10 @@ struct trie_stat {
 
 struct trie {
        struct node *trie;
+       unsigned int size;
 #ifdef CONFIG_IP_FIB_TRIE_STATS
        struct trie_use_stats stats;
 #endif
-       int size;
 };
 
 static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n);
@@ -1045,7 +1045,6 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen)
                insert_leaf_info(&l->list, li);
                goto done;
        }
-       t->size++;
        l = leaf_new();
 
        if (!l)
@@ -1261,6 +1260,8 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
        list_add_tail_rcu(&new_fa->fa_list,
                          (fa ? &fa->fa_list : fa_head));
 
+       t->size++;
+
        rt_cache_flush(-1);
        rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id,
                  &cfg->fc_nlinfo, 0);
@@ -2131,50 +2132,34 @@ static void trie_show_usage(struct seq_file *seq,
 }
 #endif /*  CONFIG_IP_FIB_TRIE_STATS */
 
+static void fib_trie_show(struct seq_file *seq, const char *name, struct trie *trie)
+{
+       struct trie_stat stat;
+
+       seq_printf(seq, "%s: %d\n", name, trie->size);
+       trie_collect_stats(trie, &stat);
+       trie_show_stats(seq, &stat);
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+       trie_show_usage(seq, &trie->stats);
+#endif
+}
 
 static int fib_triestat_seq_show(struct seq_file *seq, void *v)
 {
        struct net *net = (struct net *)seq->private;
-       struct trie *trie_local, *trie_main;
-       struct trie_stat *stat;
        struct fib_table *tb;
 
-       trie_local = NULL;
+       seq_printf(seq,
+                  "Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.\n",
+                  sizeof(struct leaf), sizeof(struct tnode));
+
        tb = fib_get_table(net, RT_TABLE_LOCAL);
        if (tb)
-               trie_local = (struct trie *) tb->tb_data;
+               fib_trie_show(seq, "Local", (struct trie *) tb->tb_data);
 
-       trie_main = NULL;
        tb = fib_get_table(net, RT_TABLE_MAIN);
        if (tb)
-               trie_main = (struct trie *) tb->tb_data;
-
-
-       stat = kmalloc(sizeof(*stat), GFP_KERNEL);
-       if (!stat)
-               return -ENOMEM;
-
-       seq_printf(seq, "Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.\n",
-                  sizeof(struct leaf), sizeof(struct tnode));
-
-       if (trie_local) {
-               seq_printf(seq, "Local:\n");
-               trie_collect_stats(trie_local, stat);
-               trie_show_stats(seq, stat);
-#ifdef CONFIG_IP_FIB_TRIE_STATS
-               trie_show_usage(seq, &trie_local->stats);
-#endif
-       }
-
-       if (trie_main) {
-               seq_printf(seq, "Main:\n");
-               trie_collect_stats(trie_main, stat);
-               trie_show_stats(seq, stat);
-#ifdef CONFIG_IP_FIB_TRIE_STATS
-               trie_show_usage(seq, &trie_main->stats);
-#endif
-       }
-       kfree(stat);
+               fib_trie_show(seq, "Main", (struct trie *) tb->tb_data);
 
        return 0;
 }