080-17-fib_trie-Remove-checks-for-index-tnode_child_length-.patch 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. From: Alexander Duyck <alexander.h.duyck@redhat.com>
  2. Date: Wed, 31 Dec 2014 10:57:02 -0800
  3. Subject: [PATCH] fib_trie: Remove checks for index >= tnode_child_length
  4. from tnode_get_child
  5. For some reason the compiler doesn't seem to understand that when we are in
  6. a loop that runs from tnode_child_length - 1 to 0 we don't expect the value
  7. of tn->bits to change. As such every call to tnode_get_child was rerunning
  8. tnode_chile_length which ended up consuming quite a bit of space in the
  9. resultant assembly code.
  10. I have gone though and verified that in all cases where tnode_get_child
  11. is used we are either winding though a fixed loop from tnode_child_length -
  12. 1 to 0, or are in a fastpath case where we are verifying the value by
  13. either checking for any remaining bits after shifting index by bits and
  14. testing for leaf, or by using tnode_child_length.
  15. size net/ipv4/fib_trie.o
  16. Before:
  17. text data bss dec hex filename
  18. 15506 376 8 15890 3e12 net/ipv4/fib_trie.o
  19. After:
  20. text data bss dec hex filename
  21. 14827 376 8 15211 3b6b net/ipv4/fib_trie.o
  22. Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
  23. Signed-off-by: David S. Miller <davem@davemloft.net>
  24. ---
  25. --- a/net/ipv4/fib_trie.c
  26. +++ b/net/ipv4/fib_trie.c
  27. @@ -186,8 +186,6 @@ static inline unsigned long tnode_child_
  28. static inline struct tnode *tnode_get_child(const struct tnode *tn,
  29. unsigned long i)
  30. {
  31. - BUG_ON(i >= tnode_child_length(tn));
  32. -
  33. return rtnl_dereference(tn->child[i]);
  34. }
  35. @@ -195,8 +193,6 @@ static inline struct tnode *tnode_get_ch
  36. static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn,
  37. unsigned long i)
  38. {
  39. - BUG_ON(i >= tnode_child_length(tn));
  40. -
  41. return rcu_dereference_rtnl(tn->child[i]);
  42. }
  43. @@ -371,7 +367,7 @@ static inline int tnode_full(const struc
  44. */
  45. static void put_child(struct tnode *tn, unsigned long i, struct tnode *n)
  46. {
  47. - struct tnode *chi = rtnl_dereference(tn->child[i]);
  48. + struct tnode *chi = tnode_get_child(tn, i);
  49. int isfull, wasfull;
  50. BUG_ON(i >= tnode_child_length(tn));
  51. @@ -867,7 +863,7 @@ static struct tnode *fib_find_node(struc
  52. if (IS_LEAF(n))
  53. break;
  54. - n = rcu_dereference_rtnl(n->child[index]);
  55. + n = tnode_get_child_rcu(n, index);
  56. }
  57. return n;
  58. @@ -934,7 +930,7 @@ static struct list_head *fib_insert_node
  59. }
  60. tp = n;
  61. - n = rcu_dereference_rtnl(n->child[index]);
  62. + n = tnode_get_child_rcu(n, index);
  63. }
  64. l = leaf_new(key);
  65. @@ -1215,7 +1211,7 @@ int fib_table_lookup(struct fib_table *t
  66. cindex = index;
  67. }
  68. - n = rcu_dereference(n->child[index]);
  69. + n = tnode_get_child_rcu(n, index);
  70. if (unlikely(!n))
  71. goto backtrace;
  72. }
  73. @@ -1835,7 +1831,7 @@ static void trie_collect_stats(struct tr
  74. if (n->bits < MAX_STAT_DEPTH)
  75. s->nodesizes[n->bits]++;
  76. - for (i = 0; i < tnode_child_length(n); i++) {
  77. + for (i = tnode_child_length(n); i--;) {
  78. if (!rcu_access_pointer(n->child[i]))
  79. s->nullpointers++;
  80. }