From 716ca530e1c4515d8683c9d5be3d56b301758b66 Mon Sep 17 00:00:00 2001 From: James <> Date: Wed, 4 Nov 2015 11:49:21 +0000 Subject: trunk-47381 --- ...move-checks-for-index-tnode_child_length-.patch | 95 ++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 target/linux/generic/patches-3.18/080-17-fib_trie-Remove-checks-for-index-tnode_child_length-.patch (limited to 'target/linux/generic/patches-3.18/080-17-fib_trie-Remove-checks-for-index-tnode_child_length-.patch') diff --git a/target/linux/generic/patches-3.18/080-17-fib_trie-Remove-checks-for-index-tnode_child_length-.patch b/target/linux/generic/patches-3.18/080-17-fib_trie-Remove-checks-for-index-tnode_child_length-.patch new file mode 100644 index 0000000..8f7c671 --- /dev/null +++ b/target/linux/generic/patches-3.18/080-17-fib_trie-Remove-checks-for-index-tnode_child_length-.patch @@ -0,0 +1,95 @@ +From: Alexander Duyck +Date: Wed, 31 Dec 2014 10:57:02 -0800 +Subject: [PATCH] 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 +Signed-off-by: David S. Miller +--- + +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -186,8 +186,6 @@ static inline unsigned long tnode_child_ + static inline struct tnode *tnode_get_child(const struct tnode *tn, + unsigned long i) + { +- BUG_ON(i >= tnode_child_length(tn)); +- + return rtnl_dereference(tn->child[i]); + } + +@@ -195,8 +193,6 @@ static inline struct tnode *tnode_get_ch + static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, + unsigned long i) + { +- BUG_ON(i >= tnode_child_length(tn)); +- + return rcu_dereference_rtnl(tn->child[i]); + } + +@@ -371,7 +367,7 @@ static inline int tnode_full(const struc + */ + static void put_child(struct tnode *tn, unsigned long i, struct tnode *n) + { +- struct tnode *chi = rtnl_dereference(tn->child[i]); ++ struct tnode *chi = tnode_get_child(tn, i); + int isfull, wasfull; + + BUG_ON(i >= tnode_child_length(tn)); +@@ -867,7 +863,7 @@ static struct tnode *fib_find_node(struc + if (IS_LEAF(n)) + break; + +- n = rcu_dereference_rtnl(n->child[index]); ++ n = tnode_get_child_rcu(n, index); + } + + return n; +@@ -934,7 +930,7 @@ static struct list_head *fib_insert_node + } + + tp = n; +- n = rcu_dereference_rtnl(n->child[index]); ++ n = tnode_get_child_rcu(n, index); + } + + l = leaf_new(key); +@@ -1215,7 +1211,7 @@ int fib_table_lookup(struct fib_table *t + cindex = index; + } + +- n = rcu_dereference(n->child[index]); ++ n = tnode_get_child_rcu(n, index); + if (unlikely(!n)) + goto backtrace; + } +@@ -1835,7 +1831,7 @@ static void trie_collect_stats(struct tr + if (n->bits < MAX_STAT_DEPTH) + s->nodesizes[n->bits]++; + +- for (i = 0; i < tnode_child_length(n); i++) { ++ for (i = tnode_child_length(n); i--;) { + if (!rcu_access_pointer(n->child[i])) + s->nullpointers++; + } -- cgit v1.2.3