#include <net/ip_fib.h>
#include "fib_lookup.h"
-#undef CONFIG_IP_FIB_TRIE_STATS
#define MAX_STAT_DEPTH 32
#define KEYLENGTH (8*sizeof(t_key))
struct trie_use_stats stats;
#endif
int size;
- unsigned int revision;
};
static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n);
static struct tnode *inflate(struct trie *t, struct tnode *tn)
{
- struct tnode *inode;
struct tnode *oldtnode = tn;
int olen = tnode_child_length(tn);
int i;
}
for (i = 0; i < olen; i++) {
+ struct tnode *inode;
struct node *node = tnode_get_child(oldtnode, i);
struct tnode *left, *right;
int size, j;
}
}
-static void trie_init(struct trie *t)
-{
- if (!t)
- return;
-
- t->size = 0;
- rcu_assign_pointer(t->trie, NULL);
- t->revision = 0;
-#ifdef CONFIG_IP_FIB_TRIE_STATS
- memset(&t->stats, 0, sizeof(struct trie_use_stats));
-#endif
-}
-
/* readside must use rcu_read_lock currently dump routines
via get_fa_head and dump */
/* only used from updater-side */
-static struct list_head *
-fib_insert_node(struct trie *t, int *err, u32 key, int plen)
+static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen)
{
int pos, newpos;
struct tnode *tp = NULL, *tn = NULL;
/* Case 1: n is a leaf. Compare prefixes */
if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) {
- struct leaf *l = (struct leaf *) n;
-
+ l = (struct leaf *) n;
li = leaf_info_new(plen);
- if (!li) {
- *err = -ENOMEM;
- goto err;
- }
+ if (!li)
+ return NULL;
fa_head = &li->falh;
insert_leaf_info(&l->list, li);
t->size++;
l = leaf_new();
- if (!l) {
- *err = -ENOMEM;
- goto err;
- }
+ if (!l)
+ return NULL;
l->key = key;
li = leaf_info_new(plen);
if (!li) {
tnode_free((struct tnode *) l);
- *err = -ENOMEM;
- goto err;
+ return NULL;
}
fa_head = &li->falh;
if (!tn) {
free_leaf_info(li);
tnode_free((struct tnode *) l);
- *err = -ENOMEM;
- goto err;
+ return NULL;
}
node_set_parent((struct node *)tn, tp);
rcu_assign_pointer(t->trie, trie_rebalance(t, tp));
done:
- t->revision++;
-err:
return fa_head;
}
*/
if (!fa_head) {
- err = 0;
- fa_head = fib_insert_node(t, &err, key, plen);
- if (err)
+ fa_head = fib_insert_node(t, key, plen);
+ if (unlikely(!fa_head)) {
+ err = -ENOMEM;
goto out_free_new_fa;
+ }
}
list_add_tail_rcu(&new_fa->fa_list,
* Remove the leaf and rebalance the tree
*/
- t->revision++;
t->size--;
tp = node_parent(n);
struct leaf *ll = NULL, *l = NULL;
int found = 0, h;
- t->revision++;
-
for (h = 0; (l = nextleaf(t, l)) != NULL; h++) {
found += trie_flush_leaf(t, l);
tb->tb_flush = fn_trie_flush;
tb->tb_select_default = fn_trie_select_default;
tb->tb_dump = fn_trie_dump;
- memset(tb->tb_data, 0, sizeof(struct trie));
t = (struct trie *) tb->tb_data;
-
- trie_init(t);
+ memset(t, 0, sizeof(*t));
if (id == RT_TABLE_LOCAL)
printk(KERN_INFO "IPv4 FIB: Using LC-trie version %s\n", VERSION);
else
avdepth = 0;
- seq_printf(seq, "\tAver depth: %d.%02d\n", avdepth / 100, avdepth % 100 );
+ seq_printf(seq, "\tAver depth: %u.%02d\n", avdepth / 100, avdepth % 100 );
seq_printf(seq, "\tMax depth: %u\n", stat->maxdepth);
seq_printf(seq, "\tLeaves: %u\n", stat->leaves);
bytes = sizeof(struct leaf) * stat->leaves;
- seq_printf(seq, "\tInternal nodes: %d\n\t", stat->tnodes);
+ seq_printf(seq, "\tInternal nodes: %u\n\t", stat->tnodes);
bytes += sizeof(struct tnode) * stat->tnodes;
max = MAX_STAT_DEPTH;
pointers = 0;
for (i = 1; i <= max; i++)
if (stat->nodesizes[i] != 0) {
- seq_printf(seq, " %d: %d", i, stat->nodesizes[i]);
+ seq_printf(seq, " %u: %u", i, stat->nodesizes[i]);
pointers += (1<<i) * stat->nodesizes[i];
}
seq_putc(seq, '\n');
- seq_printf(seq, "\tPointers: %d\n", pointers);
+ seq_printf(seq, "\tPointers: %u\n", pointers);
bytes += sizeof(struct node *) * pointers;
- seq_printf(seq, "Null ptrs: %d\n", stat->nullpointers);
- seq_printf(seq, "Total size: %d kB\n", (bytes + 1023) / 1024);
+ seq_printf(seq, "Null ptrs: %u\n", stat->nullpointers);
+ seq_printf(seq, "Total size: %u kB\n", (bytes + 1023) / 1024);
+}
#ifdef CONFIG_IP_FIB_TRIE_STATS
- seq_printf(seq, "Counters:\n---------\n");
- seq_printf(seq,"gets = %d\n", t->stats.gets);
- seq_printf(seq,"backtracks = %d\n", t->stats.backtrack);
- seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed);
- seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss);
- seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit);
- seq_printf(seq,"skipped node resize = %d\n", t->stats.resize_node_skipped);
-#ifdef CLEAR_STATS
- memset(&(t->stats), 0, sizeof(t->stats));
-#endif
-#endif /* CONFIG_IP_FIB_TRIE_STATS */
+static void trie_show_usage(struct seq_file *seq,
+ const struct trie_use_stats *stats)
+{
+ seq_printf(seq, "\nCounters:\n---------\n");
+ seq_printf(seq,"gets = %u\n", stats->gets);
+ seq_printf(seq,"backtracks = %u\n", stats->backtrack);
+ seq_printf(seq,"semantic match passed = %u\n", stats->semantic_match_passed);
+ seq_printf(seq,"semantic match miss = %u\n", stats->semantic_match_miss);
+ seq_printf(seq,"null node hit= %u\n", stats->null_node_hit);
+ seq_printf(seq,"skipped node resize = %u\n\n", stats->resize_node_skipped);
}
+#endif /* CONFIG_IP_FIB_TRIE_STATS */
+
static int fib_triestat_seq_show(struct seq_file *seq, void *v)
{
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);
}
static void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
struct fib_trie_iter *iter = seq->private;
struct fib_table *tb;
}
static void fib_trie_seq_stop(struct seq_file *seq, void *v)
+ __releases(RCU)
{
rcu_read_unlock();
}
if (t < __RTN_MAX && rtn_type_names[t])
return rtn_type_names[t];
- snprintf(buf, sizeof(buf), "type %d", t);
+ snprintf(buf, sizeof(buf), "type %u", t);
return buf;
}