080-07-fib_trie-Optimize-fib_find_node.patch 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. From: Alexander Duyck <alexander.h.duyck@redhat.com>
  2. Date: Wed, 31 Dec 2014 10:56:00 -0800
  3. Subject: [PATCH] fib_trie: Optimize fib_find_node
  4. This patch makes use of the same features I made use of for
  5. fib_table_lookup to streamline fib_find_node. The resultant code should be
  6. smaller and run faster than the original.
  7. Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
  8. Signed-off-by: David S. Miller <davem@davemloft.net>
  9. ---
  10. --- a/net/ipv4/fib_trie.c
  11. +++ b/net/ipv4/fib_trie.c
  12. @@ -892,28 +892,34 @@ static void insert_leaf_info(struct hlis
  13. }
  14. /* rcu_read_lock needs to be hold by caller from readside */
  15. -
  16. static struct tnode *fib_find_node(struct trie *t, u32 key)
  17. {
  18. struct tnode *n = rcu_dereference_rtnl(t->trie);
  19. - int pos = 0;
  20. - while (n && IS_TNODE(n)) {
  21. - if (tkey_sub_equals(n->key, pos, n->pos-pos, key)) {
  22. - pos = n->pos + n->bits;
  23. - n = tnode_get_child_rcu(n,
  24. - tkey_extract_bits(key,
  25. - n->pos,
  26. - n->bits));
  27. - } else
  28. + while (n) {
  29. + unsigned long index = get_index(key, n);
  30. +
  31. + /* This bit of code is a bit tricky but it combines multiple
  32. + * checks into a single check. The prefix consists of the
  33. + * prefix plus zeros for the bits in the cindex. The index
  34. + * is the difference between the key and this value. From
  35. + * this we can actually derive several pieces of data.
  36. + * if !(index >> bits)
  37. + * we know the value is cindex
  38. + * else
  39. + * we have a mismatch in skip bits and failed
  40. + */
  41. + if (index >> n->bits)
  42. + return NULL;
  43. +
  44. + /* we have found a leaf. Prefixes have already been compared */
  45. + if (IS_LEAF(n))
  46. break;
  47. - }
  48. - /* Case we have found a leaf. Compare prefixes */
  49. - if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key))
  50. - return n;
  51. + n = rcu_dereference_rtnl(n->child[index]);
  52. + }
  53. - return NULL;
  54. + return n;
  55. }
  56. static void trie_rebalance(struct trie *t, struct tnode *tn)