diff options
author | Alexander Duyck <alexander.h.duyck@redhat.com> | 2014-12-31 13:56:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-12-31 18:25:54 -0500 |
commit | 939afb0657dd8c8f9486d172d6bb62fc902e2f23 (patch) | |
tree | eeb5b3e7dbd11bd700c0f726c152c2d973870bc1 /net/ipv4 | |
parent | 9f9e636d4f89f788c5cf9c6a5357501c0d405fcb (diff) |
fib_trie: Optimize fib_find_node
This patch makes use of the same features I made use of for
fib_table_lookup to streamline fib_find_node. The resultant code should be
smaller and run faster than the original.
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/fib_trie.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 3fe4dd917ce1..ac04f31a632e 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -892,28 +892,34 @@ static void insert_leaf_info(struct hlist_head *head, struct leaf_info *new) | |||
892 | } | 892 | } |
893 | 893 | ||
894 | /* rcu_read_lock needs to be hold by caller from readside */ | 894 | /* rcu_read_lock needs to be hold by caller from readside */ |
895 | |||
896 | static struct tnode *fib_find_node(struct trie *t, u32 key) | 895 | static struct tnode *fib_find_node(struct trie *t, u32 key) |
897 | { | 896 | { |
898 | struct tnode *n = rcu_dereference_rtnl(t->trie); | 897 | struct tnode *n = rcu_dereference_rtnl(t->trie); |
899 | int pos = 0; | ||
900 | 898 | ||
901 | while (n && IS_TNODE(n)) { | 899 | while (n) { |
902 | if (tkey_sub_equals(n->key, pos, n->pos-pos, key)) { | 900 | unsigned long index = get_index(key, n); |
903 | pos = n->pos + n->bits; | 901 | |
904 | n = tnode_get_child_rcu(n, | 902 | /* This bit of code is a bit tricky but it combines multiple |
905 | tkey_extract_bits(key, | 903 | * checks into a single check. The prefix consists of the |
906 | n->pos, | 904 | * prefix plus zeros for the bits in the cindex. The index |
907 | n->bits)); | 905 | * is the difference between the key and this value. From |
908 | } else | 906 | * this we can actually derive several pieces of data. |
907 | * if !(index >> bits) | ||
908 | * we know the value is cindex | ||
909 | * else | ||
910 | * we have a mismatch in skip bits and failed | ||
911 | */ | ||
912 | if (index >> n->bits) | ||
913 | return NULL; | ||
914 | |||
915 | /* we have found a leaf. Prefixes have already been compared */ | ||
916 | if (IS_LEAF(n)) | ||
909 | break; | 917 | break; |
910 | } | ||
911 | /* Case we have found a leaf. Compare prefixes */ | ||
912 | 918 | ||
913 | if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) | 919 | n = rcu_dereference_rtnl(n->child[index]); |
914 | return n; | 920 | } |
915 | 921 | ||
916 | return NULL; | 922 | return n; |
917 | } | 923 | } |
918 | 924 | ||
919 | static void trie_rebalance(struct trie *t, struct tnode *tn) | 925 | static void trie_rebalance(struct trie *t, struct tnode *tn) |