diff options
author | Alexander Duyck <alexander.h.duyck@redhat.com> | 2014-12-31 13:57:02 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-12-31 18:25:55 -0500 |
commit | 21d1f11db0e2f20a549ad8322879507850544670 (patch) | |
tree | b8e624c9b2d1426f74d39090e982037daabb2d2f /net | |
parent | 12c081a5c82ef64a90906247cecfa5422962e387 (diff) |
fib_trie: Remove checks for index >= tnode_child_length from tnode_get_child
For some reason the compiler doesn't seem to understand that when we are in
a loop that runs from tnode_child_length - 1 to 0 we don't expect the value
of tn->bits to change. As such every call to tnode_get_child was rerunning
tnode_chile_length which ended up consuming quite a bit of space in the
resultant assembly code.
I have gone though and verified that in all cases where tnode_get_child
is used we are either winding though a fixed loop from tnode_child_length -
1 to 0, or are in a fastpath case where we are verifying the value by
either checking for any remaining bits after shifting index by bits and
testing for leaf, or by using tnode_child_length.
size net/ipv4/fib_trie.o
Before:
text data bss dec hex filename
15506 376 8 15890 3e12 net/ipv4/fib_trie.o
After:
text data bss dec hex filename
14827 376 8 15211 3b6b net/ipv4/fib_trie.o
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/fib_trie.c | 14 |
1 files changed, 5 insertions, 9 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 0c88df09d25d..87fc9a466fa2 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -186,8 +186,6 @@ static inline unsigned long tnode_child_length(const struct tnode *tn) | |||
186 | static inline struct tnode *tnode_get_child(const struct tnode *tn, | 186 | static inline struct tnode *tnode_get_child(const struct tnode *tn, |
187 | unsigned long i) | 187 | unsigned long i) |
188 | { | 188 | { |
189 | BUG_ON(i >= tnode_child_length(tn)); | ||
190 | |||
191 | return rtnl_dereference(tn->child[i]); | 189 | return rtnl_dereference(tn->child[i]); |
192 | } | 190 | } |
193 | 191 | ||
@@ -195,8 +193,6 @@ static inline struct tnode *tnode_get_child(const struct tnode *tn, | |||
195 | static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, | 193 | static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, |
196 | unsigned long i) | 194 | unsigned long i) |
197 | { | 195 | { |
198 | BUG_ON(i >= tnode_child_length(tn)); | ||
199 | |||
200 | return rcu_dereference_rtnl(tn->child[i]); | 196 | return rcu_dereference_rtnl(tn->child[i]); |
201 | } | 197 | } |
202 | 198 | ||
@@ -371,7 +367,7 @@ static inline int tnode_full(const struct tnode *tn, const struct tnode *n) | |||
371 | */ | 367 | */ |
372 | static void put_child(struct tnode *tn, unsigned long i, struct tnode *n) | 368 | static void put_child(struct tnode *tn, unsigned long i, struct tnode *n) |
373 | { | 369 | { |
374 | struct tnode *chi = rtnl_dereference(tn->child[i]); | 370 | struct tnode *chi = tnode_get_child(tn, i); |
375 | int isfull, wasfull; | 371 | int isfull, wasfull; |
376 | 372 | ||
377 | BUG_ON(i >= tnode_child_length(tn)); | 373 | BUG_ON(i >= tnode_child_length(tn)); |
@@ -867,7 +863,7 @@ static struct tnode *fib_find_node(struct trie *t, u32 key) | |||
867 | if (IS_LEAF(n)) | 863 | if (IS_LEAF(n)) |
868 | break; | 864 | break; |
869 | 865 | ||
870 | n = rcu_dereference_rtnl(n->child[index]); | 866 | n = tnode_get_child_rcu(n, index); |
871 | } | 867 | } |
872 | 868 | ||
873 | return n; | 869 | return n; |
@@ -934,7 +930,7 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen) | |||
934 | } | 930 | } |
935 | 931 | ||
936 | tp = n; | 932 | tp = n; |
937 | n = rcu_dereference_rtnl(n->child[index]); | 933 | n = tnode_get_child_rcu(n, index); |
938 | } | 934 | } |
939 | 935 | ||
940 | l = leaf_new(key); | 936 | l = leaf_new(key); |
@@ -1215,7 +1211,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, | |||
1215 | cindex = index; | 1211 | cindex = index; |
1216 | } | 1212 | } |
1217 | 1213 | ||
1218 | n = rcu_dereference(n->child[index]); | 1214 | n = tnode_get_child_rcu(n, index); |
1219 | if (unlikely(!n)) | 1215 | if (unlikely(!n)) |
1220 | goto backtrace; | 1216 | goto backtrace; |
1221 | } | 1217 | } |
@@ -1835,7 +1831,7 @@ static void trie_collect_stats(struct trie *t, struct trie_stat *s) | |||
1835 | if (n->bits < MAX_STAT_DEPTH) | 1831 | if (n->bits < MAX_STAT_DEPTH) |
1836 | s->nodesizes[n->bits]++; | 1832 | s->nodesizes[n->bits]++; |
1837 | 1833 | ||
1838 | for (i = 0; i < tnode_child_length(n); i++) { | 1834 | for (i = tnode_child_length(n); i--;) { |
1839 | if (!rcu_access_pointer(n->child[i])) | 1835 | if (!rcu_access_pointer(n->child[i])) |
1840 | s->nullpointers++; | 1836 | s->nullpointers++; |
1841 | } | 1837 | } |