080-01-fib_trie-Fix-trie-balancing-issue-if-new-node-pushes.patch 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. From: Alexander Duyck <alexander.h.duyck@redhat.com>
  2. Date: Wed, 10 Dec 2014 21:49:22 -0800
  3. Subject: [PATCH] fib_trie: Fix trie balancing issue if new node pushes down
  4. existing node
  5. This patch addresses an issue with the level compression of the fib_trie.
  6. Specifically in the case of adding a new leaf that triggers a new node to
  7. be added that takes the place of the old node. The result is a trie where
  8. the 1 child tnode is on one side and one leaf is on the other which gives
  9. you a very deep trie. Below is the script I used to generate a trie on
  10. dummy0 with a 10.X.X.X family of addresses.
  11. ip link add type dummy
  12. ipval=184549374
  13. bit=2
  14. for i in `seq 1 23`
  15. do
  16. ifconfig dummy0:$bit $ipval/8
  17. ipval=`expr $ipval - $bit`
  18. bit=`expr $bit \* 2`
  19. done
  20. cat /proc/net/fib_triestat
  21. Running the script before the patch:
  22. Local:
  23. Aver depth: 10.82
  24. Max depth: 23
  25. Leaves: 29
  26. Prefixes: 30
  27. Internal nodes: 27
  28. 1: 26 2: 1
  29. Pointers: 56
  30. Null ptrs: 1
  31. Total size: 5 kB
  32. After applying the patch and repeating:
  33. Local:
  34. Aver depth: 4.72
  35. Max depth: 9
  36. Leaves: 29
  37. Prefixes: 30
  38. Internal nodes: 12
  39. 1: 3 2: 2 3: 7
  40. Pointers: 70
  41. Null ptrs: 30
  42. Total size: 4 kB
  43. What this fix does is start the rebalance at the newly created tnode
  44. instead of at the parent tnode. This way if there is a gap between the
  45. parent and the new node it doesn't prevent the new tnode from being
  46. coalesced with any pre-existing nodes that may have been pushed into one
  47. of the new nodes child branches.
  48. Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
  49. Signed-off-by: David S. Miller <davem@davemloft.net>
  50. ---
  51. --- a/net/ipv4/fib_trie.c
  52. +++ b/net/ipv4/fib_trie.c
  53. @@ -1143,8 +1143,9 @@ static struct list_head *fib_insert_node
  54. put_child(tp, cindex, (struct rt_trie_node *)tn);
  55. } else {
  56. rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn);
  57. - tp = tn;
  58. }
  59. +
  60. + tp = tn;
  61. }
  62. if (tp && tp->pos + tp->bits > 32)