From 716ca530e1c4515d8683c9d5be3d56b301758b66 Mon Sep 17 00:00:00 2001 From: James <> Date: Wed, 4 Nov 2015 11:49:21 +0000 Subject: trunk-47381 --- ...b_trie-Move-resize-to-after-inflate-halve.patch | 345 +++++++++++++++++++++ 1 file changed, 345 insertions(+) create mode 100644 target/linux/generic/patches-3.18/080-12-fib_trie-Move-resize-to-after-inflate-halve.patch (limited to 'target/linux/generic/patches-3.18/080-12-fib_trie-Move-resize-to-after-inflate-halve.patch') diff --git a/target/linux/generic/patches-3.18/080-12-fib_trie-Move-resize-to-after-inflate-halve.patch b/target/linux/generic/patches-3.18/080-12-fib_trie-Move-resize-to-after-inflate-halve.patch new file mode 100644 index 0000000..a373add --- /dev/null +++ b/target/linux/generic/patches-3.18/080-12-fib_trie-Move-resize-to-after-inflate-halve.patch @@ -0,0 +1,345 @@ +From: Alexander Duyck +Date: Wed, 31 Dec 2014 10:56:31 -0800 +Subject: [PATCH] fib_trie: Move resize to after inflate/halve + +This change consists of a cut/paste of resize to behind inflate and halve +so that I could remove the two function prototypes. + +Signed-off-by: Alexander Duyck +Signed-off-by: David S. Miller +--- + +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -149,8 +149,6 @@ struct trie { + static void tnode_put_child_reorg(struct tnode *tn, unsigned long i, + struct tnode *n, int wasfull); + static struct tnode *resize(struct trie *t, struct tnode *tn); +-static struct tnode *inflate(struct trie *t, struct tnode *tn); +-static struct tnode *halve(struct trie *t, struct tnode *tn); + /* tnodes to free after resize(); protected by RTNL */ + static struct callback_head *tnode_free_head; + static size_t tnode_free_size; +@@ -447,161 +445,6 @@ static void put_child_root(struct tnode + rcu_assign_pointer(t->trie, n); + } + +-#define MAX_WORK 10 +-static struct tnode *resize(struct trie *t, struct tnode *tn) +-{ +- struct tnode *old_tn, *n = NULL; +- int inflate_threshold_use; +- int halve_threshold_use; +- int max_work; +- +- if (!tn) +- return NULL; +- +- pr_debug("In tnode_resize %p inflate_threshold=%d threshold=%d\n", +- tn, inflate_threshold, halve_threshold); +- +- /* No children */ +- if (tn->empty_children > (tnode_child_length(tn) - 1)) +- goto no_children; +- +- /* One child */ +- if (tn->empty_children == (tnode_child_length(tn) - 1)) +- goto one_child; +- /* +- * Double as long as the resulting node has a number of +- * nonempty nodes that are above the threshold. +- */ +- +- /* +- * From "Implementing a dynamic compressed trie" by Stefan Nilsson of +- * the Helsinki University of Technology and Matti Tikkanen of Nokia +- * Telecommunications, page 6: +- * "A node is doubled if the ratio of non-empty children to all +- * children in the *doubled* node is at least 'high'." +- * +- * 'high' in this instance is the variable 'inflate_threshold'. It +- * is expressed as a percentage, so we multiply it with +- * tnode_child_length() and instead of multiplying by 2 (since the +- * child array will be doubled by inflate()) and multiplying +- * the left-hand side by 100 (to handle the percentage thing) we +- * multiply the left-hand side by 50. +- * +- * The left-hand side may look a bit weird: tnode_child_length(tn) +- * - tn->empty_children is of course the number of non-null children +- * in the current node. tn->full_children is the number of "full" +- * children, that is non-null tnodes with a skip value of 0. +- * All of those will be doubled in the resulting inflated tnode, so +- * we just count them one extra time here. +- * +- * A clearer way to write this would be: +- * +- * to_be_doubled = tn->full_children; +- * not_to_be_doubled = tnode_child_length(tn) - tn->empty_children - +- * tn->full_children; +- * +- * new_child_length = tnode_child_length(tn) * 2; +- * +- * new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) / +- * new_child_length; +- * if (new_fill_factor >= inflate_threshold) +- * +- * ...and so on, tho it would mess up the while () loop. +- * +- * anyway, +- * 100 * (not_to_be_doubled + 2*to_be_doubled) / new_child_length >= +- * inflate_threshold +- * +- * avoid a division: +- * 100 * (not_to_be_doubled + 2*to_be_doubled) >= +- * inflate_threshold * new_child_length +- * +- * expand not_to_be_doubled and to_be_doubled, and shorten: +- * 100 * (tnode_child_length(tn) - tn->empty_children + +- * tn->full_children) >= inflate_threshold * new_child_length +- * +- * expand new_child_length: +- * 100 * (tnode_child_length(tn) - tn->empty_children + +- * tn->full_children) >= +- * inflate_threshold * tnode_child_length(tn) * 2 +- * +- * shorten again: +- * 50 * (tn->full_children + tnode_child_length(tn) - +- * tn->empty_children) >= inflate_threshold * +- * tnode_child_length(tn) +- * +- */ +- +- /* Keep root node larger */ +- +- if (!node_parent(tn)) { +- inflate_threshold_use = inflate_threshold_root; +- halve_threshold_use = halve_threshold_root; +- } else { +- inflate_threshold_use = inflate_threshold; +- halve_threshold_use = halve_threshold; +- } +- +- max_work = MAX_WORK; +- while ((tn->full_children > 0 && max_work-- && +- 50 * (tn->full_children + tnode_child_length(tn) +- - tn->empty_children) +- >= inflate_threshold_use * tnode_child_length(tn))) { +- +- old_tn = tn; +- tn = inflate(t, tn); +- +- if (IS_ERR(tn)) { +- tn = old_tn; +-#ifdef CONFIG_IP_FIB_TRIE_STATS +- this_cpu_inc(t->stats->resize_node_skipped); +-#endif +- break; +- } +- } +- +- /* Return if at least one inflate is run */ +- if (max_work != MAX_WORK) +- return tn; +- +- /* +- * Halve as long as the number of empty children in this +- * node is above threshold. +- */ +- +- max_work = MAX_WORK; +- while (tn->bits > 1 && max_work-- && +- 100 * (tnode_child_length(tn) - tn->empty_children) < +- halve_threshold_use * tnode_child_length(tn)) { +- +- old_tn = tn; +- tn = halve(t, tn); +- if (IS_ERR(tn)) { +- tn = old_tn; +-#ifdef CONFIG_IP_FIB_TRIE_STATS +- this_cpu_inc(t->stats->resize_node_skipped); +-#endif +- break; +- } +- } +- +- +- /* Only one child remains */ +- if (tn->empty_children == (tnode_child_length(tn) - 1)) { +- unsigned long i; +-one_child: +- for (i = tnode_child_length(tn); !n && i;) +- n = tnode_get_child(tn, --i); +-no_children: +- /* compress one level */ +- node_set_parent(n, NULL); +- tnode_free_safe(tn); +- return n; +- } +- return tn; +-} +- +- + static void tnode_clean_free(struct tnode *tn) + { + struct tnode *tofree; +@@ -804,6 +647,160 @@ nomem: + return ERR_PTR(-ENOMEM); + } + ++#define MAX_WORK 10 ++static struct tnode *resize(struct trie *t, struct tnode *tn) ++{ ++ struct tnode *old_tn, *n = NULL; ++ int inflate_threshold_use; ++ int halve_threshold_use; ++ int max_work; ++ ++ if (!tn) ++ return NULL; ++ ++ pr_debug("In tnode_resize %p inflate_threshold=%d threshold=%d\n", ++ tn, inflate_threshold, halve_threshold); ++ ++ /* No children */ ++ if (tn->empty_children > (tnode_child_length(tn) - 1)) ++ goto no_children; ++ ++ /* One child */ ++ if (tn->empty_children == (tnode_child_length(tn) - 1)) ++ goto one_child; ++ /* ++ * Double as long as the resulting node has a number of ++ * nonempty nodes that are above the threshold. ++ */ ++ ++ /* ++ * From "Implementing a dynamic compressed trie" by Stefan Nilsson of ++ * the Helsinki University of Technology and Matti Tikkanen of Nokia ++ * Telecommunications, page 6: ++ * "A node is doubled if the ratio of non-empty children to all ++ * children in the *doubled* node is at least 'high'." ++ * ++ * 'high' in this instance is the variable 'inflate_threshold'. It ++ * is expressed as a percentage, so we multiply it with ++ * tnode_child_length() and instead of multiplying by 2 (since the ++ * child array will be doubled by inflate()) and multiplying ++ * the left-hand side by 100 (to handle the percentage thing) we ++ * multiply the left-hand side by 50. ++ * ++ * The left-hand side may look a bit weird: tnode_child_length(tn) ++ * - tn->empty_children is of course the number of non-null children ++ * in the current node. tn->full_children is the number of "full" ++ * children, that is non-null tnodes with a skip value of 0. ++ * All of those will be doubled in the resulting inflated tnode, so ++ * we just count them one extra time here. ++ * ++ * A clearer way to write this would be: ++ * ++ * to_be_doubled = tn->full_children; ++ * not_to_be_doubled = tnode_child_length(tn) - tn->empty_children - ++ * tn->full_children; ++ * ++ * new_child_length = tnode_child_length(tn) * 2; ++ * ++ * new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) / ++ * new_child_length; ++ * if (new_fill_factor >= inflate_threshold) ++ * ++ * ...and so on, tho it would mess up the while () loop. ++ * ++ * anyway, ++ * 100 * (not_to_be_doubled + 2*to_be_doubled) / new_child_length >= ++ * inflate_threshold ++ * ++ * avoid a division: ++ * 100 * (not_to_be_doubled + 2*to_be_doubled) >= ++ * inflate_threshold * new_child_length ++ * ++ * expand not_to_be_doubled and to_be_doubled, and shorten: ++ * 100 * (tnode_child_length(tn) - tn->empty_children + ++ * tn->full_children) >= inflate_threshold * new_child_length ++ * ++ * expand new_child_length: ++ * 100 * (tnode_child_length(tn) - tn->empty_children + ++ * tn->full_children) >= ++ * inflate_threshold * tnode_child_length(tn) * 2 ++ * ++ * shorten again: ++ * 50 * (tn->full_children + tnode_child_length(tn) - ++ * tn->empty_children) >= inflate_threshold * ++ * tnode_child_length(tn) ++ * ++ */ ++ ++ /* Keep root node larger */ ++ ++ if (!node_parent(tn)) { ++ inflate_threshold_use = inflate_threshold_root; ++ halve_threshold_use = halve_threshold_root; ++ } else { ++ inflate_threshold_use = inflate_threshold; ++ halve_threshold_use = halve_threshold; ++ } ++ ++ max_work = MAX_WORK; ++ while ((tn->full_children > 0 && max_work-- && ++ 50 * (tn->full_children + tnode_child_length(tn) ++ - tn->empty_children) ++ >= inflate_threshold_use * tnode_child_length(tn))) { ++ ++ old_tn = tn; ++ tn = inflate(t, tn); ++ ++ if (IS_ERR(tn)) { ++ tn = old_tn; ++#ifdef CONFIG_IP_FIB_TRIE_STATS ++ this_cpu_inc(t->stats->resize_node_skipped); ++#endif ++ break; ++ } ++ } ++ ++ /* Return if at least one inflate is run */ ++ if (max_work != MAX_WORK) ++ return tn; ++ ++ /* ++ * Halve as long as the number of empty children in this ++ * node is above threshold. ++ */ ++ ++ max_work = MAX_WORK; ++ while (tn->bits > 1 && max_work-- && ++ 100 * (tnode_child_length(tn) - tn->empty_children) < ++ halve_threshold_use * tnode_child_length(tn)) { ++ ++ old_tn = tn; ++ tn = halve(t, tn); ++ if (IS_ERR(tn)) { ++ tn = old_tn; ++#ifdef CONFIG_IP_FIB_TRIE_STATS ++ this_cpu_inc(t->stats->resize_node_skipped); ++#endif ++ break; ++ } ++ } ++ ++ ++ /* Only one child remains */ ++ if (tn->empty_children == (tnode_child_length(tn) - 1)) { ++ unsigned long i; ++one_child: ++ for (i = tnode_child_length(tn); !n && i;) ++ n = tnode_get_child(tn, --i); ++no_children: ++ /* compress one level */ ++ node_set_parent(n, NULL); ++ tnode_free_safe(tn); ++ return n; ++ } ++ return tn; ++} ++ + /* readside must use rcu_read_lock currently dump routines + via get_fa_head and dump */ + -- cgit v1.2.3