aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/pending-3.18/080-03-fib_trie-Make-leaf-and-tnode-more-uniform.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/pending-3.18/080-03-fib_trie-Make-leaf-and-tnode-more-uniform.patch')
-rw-r--r--target/linux/generic/pending-3.18/080-03-fib_trie-Make-leaf-and-tnode-more-uniform.patch421
1 files changed, 0 insertions, 421 deletions
diff --git a/target/linux/generic/pending-3.18/080-03-fib_trie-Make-leaf-and-tnode-more-uniform.patch b/target/linux/generic/pending-3.18/080-03-fib_trie-Make-leaf-and-tnode-more-uniform.patch
deleted file mode 100644
index 4c727cdfce..0000000000
--- a/target/linux/generic/pending-3.18/080-03-fib_trie-Make-leaf-and-tnode-more-uniform.patch
+++ /dev/null
@@ -1,421 +0,0 @@
-From: Alexander Duyck <alexander.h.duyck@redhat.com>
-Date: Wed, 31 Dec 2014 10:55:35 -0800
-Subject: [PATCH] fib_trie: Make leaf and tnode more uniform
-
-This change makes some fundamental changes to the way leaves and tnodes are
-constructed. The big differences are:
-1. Leaves now populate pos and bits indicating their full key size.
-2. Trie nodes now mask out their lower bits to be consistent with the leaf
-3. Both structures have been reordered so that rt_trie_node now consisists
- of a much larger region including the pos, bits, and rcu portions of
- the tnode structure.
-
-On 32b systems this will result in the leaf being 4B larger as the pos and
-bits values were added to a hole created by the key as it was only 4B in
-length.
-
-Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/net/ipv4/fib_trie.c
-+++ b/net/ipv4/fib_trie.c
-@@ -87,24 +87,38 @@
-
- typedef unsigned int t_key;
-
--#define T_TNODE 0
--#define T_LEAF 1
--#define NODE_TYPE_MASK 0x1UL
--#define NODE_TYPE(node) ((node)->parent & NODE_TYPE_MASK)
-+#define IS_TNODE(n) ((n)->bits)
-+#define IS_LEAF(n) (!(n)->bits)
-
--#define IS_TNODE(n) (!(n->parent & T_LEAF))
--#define IS_LEAF(n) (n->parent & T_LEAF)
-+struct tnode {
-+ t_key key;
-+ unsigned char bits; /* 2log(KEYLENGTH) bits needed */
-+ unsigned char pos; /* 2log(KEYLENGTH) bits needed */
-+ struct tnode __rcu *parent;
-+ union {
-+ struct rcu_head rcu;
-+ struct tnode *tnode_free;
-+ };
-+ unsigned int full_children; /* KEYLENGTH bits needed */
-+ unsigned int empty_children; /* KEYLENGTH bits needed */
-+ struct rt_trie_node __rcu *child[0];
-+};
-
- struct rt_trie_node {
-- unsigned long parent;
- t_key key;
-+ unsigned char bits;
-+ unsigned char pos;
-+ struct tnode __rcu *parent;
-+ struct rcu_head rcu;
- };
-
- struct leaf {
-- unsigned long parent;
- t_key key;
-- struct hlist_head list;
-+ unsigned char bits;
-+ unsigned char pos;
-+ struct tnode __rcu *parent;
- struct rcu_head rcu;
-+ struct hlist_head list;
- };
-
- struct leaf_info {
-@@ -115,20 +129,6 @@ struct leaf_info {
- struct rcu_head rcu;
- };
-
--struct tnode {
-- unsigned long parent;
-- t_key key;
-- unsigned char pos; /* 2log(KEYLENGTH) bits needed */
-- unsigned char bits; /* 2log(KEYLENGTH) bits needed */
-- unsigned int full_children; /* KEYLENGTH bits needed */
-- unsigned int empty_children; /* KEYLENGTH bits needed */
-- union {
-- struct rcu_head rcu;
-- struct tnode *tnode_free;
-- };
-- struct rt_trie_node __rcu *child[0];
--};
--
- #ifdef CONFIG_IP_FIB_TRIE_STATS
- struct trie_use_stats {
- unsigned int gets;
-@@ -176,38 +176,27 @@ static const int sync_pages = 128;
- static struct kmem_cache *fn_alias_kmem __read_mostly;
- static struct kmem_cache *trie_leaf_kmem __read_mostly;
-
--/*
-- * caller must hold RTNL
-- */
--static inline struct tnode *node_parent(const struct rt_trie_node *node)
--{
-- unsigned long parent;
-+/* caller must hold RTNL */
-+#define node_parent(n) rtnl_dereference((n)->parent)
-
-- parent = rcu_dereference_index_check(node->parent, lockdep_rtnl_is_held());
-+/* caller must hold RCU read lock or RTNL */
-+#define node_parent_rcu(n) rcu_dereference_rtnl((n)->parent)
-
-- return (struct tnode *)(parent & ~NODE_TYPE_MASK);
--}
--
--/*
-- * caller must hold RCU read lock or RTNL
-- */
--static inline struct tnode *node_parent_rcu(const struct rt_trie_node *node)
-+/* wrapper for rcu_assign_pointer */
-+static inline void node_set_parent(struct rt_trie_node *node, struct tnode *ptr)
- {
-- unsigned long parent;
--
-- parent = rcu_dereference_index_check(node->parent, rcu_read_lock_held() ||
-- lockdep_rtnl_is_held());
--
-- return (struct tnode *)(parent & ~NODE_TYPE_MASK);
-+ if (node)
-+ rcu_assign_pointer(node->parent, ptr);
- }
-
--/* Same as rcu_assign_pointer
-- * but that macro() assumes that value is a pointer.
-+#define NODE_INIT_PARENT(n, p) RCU_INIT_POINTER((n)->parent, p)
-+
-+/* This provides us with the number of children in this node, in the case of a
-+ * leaf this will return 0 meaning none of the children are accessible.
- */
--static inline void node_set_parent(struct rt_trie_node *node, struct tnode *ptr)
-+static inline int tnode_child_length(const struct tnode *tn)
- {
-- smp_wmb();
-- node->parent = (unsigned long)ptr | NODE_TYPE(node);
-+ return (1ul << tn->bits) & ~(1ul);
- }
-
- /*
-@@ -215,7 +204,7 @@ static inline void node_set_parent(struc
- */
- static inline struct rt_trie_node *tnode_get_child(const struct tnode *tn, unsigned int i)
- {
-- BUG_ON(i >= 1U << tn->bits);
-+ BUG_ON(i >= tnode_child_length(tn));
-
- return rtnl_dereference(tn->child[i]);
- }
-@@ -225,16 +214,11 @@ static inline struct rt_trie_node *tnode
- */
- static inline struct rt_trie_node *tnode_get_child_rcu(const struct tnode *tn, unsigned int i)
- {
-- BUG_ON(i >= 1U << tn->bits);
-+ BUG_ON(i >= tnode_child_length(tn));
-
- return rcu_dereference_rtnl(tn->child[i]);
- }
-
--static inline int tnode_child_length(const struct tnode *tn)
--{
-- return 1 << tn->bits;
--}
--
- static inline t_key mask_pfx(t_key k, unsigned int l)
- {
- return (l == 0) ? 0 : k >> (KEYLENGTH-l) << (KEYLENGTH-l);
-@@ -336,11 +320,6 @@ static inline int tkey_mismatch(t_key a,
-
- */
-
--static inline void check_tnode(const struct tnode *tn)
--{
-- WARN_ON(tn && tn->pos+tn->bits > 32);
--}
--
- static const int halve_threshold = 25;
- static const int inflate_threshold = 50;
- static const int halve_threshold_root = 15;
-@@ -426,11 +405,20 @@ static void tnode_free_flush(void)
- }
- }
-
--static struct leaf *leaf_new(void)
-+static struct leaf *leaf_new(t_key key)
- {
- struct leaf *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL);
- if (l) {
-- l->parent = T_LEAF;
-+ l->parent = NULL;
-+ /* set key and pos to reflect full key value
-+ * any trailing zeros in the key should be ignored
-+ * as the nodes are searched
-+ */
-+ l->key = key;
-+ l->pos = KEYLENGTH;
-+ /* set bits to 0 indicating we are not a tnode */
-+ l->bits = 0;
-+
- INIT_HLIST_HEAD(&l->list);
- }
- return l;
-@@ -451,12 +439,16 @@ static struct tnode *tnode_new(t_key key
- {
- size_t sz = sizeof(struct tnode) + (sizeof(struct rt_trie_node *) << bits);
- struct tnode *tn = tnode_alloc(sz);
-+ unsigned int shift = pos + bits;
-+
-+ /* verify bits and pos their msb bits clear and values are valid */
-+ BUG_ON(!bits || (shift > KEYLENGTH));
-
- if (tn) {
-- tn->parent = T_TNODE;
-+ tn->parent = NULL;
- tn->pos = pos;
- tn->bits = bits;
-- tn->key = key;
-+ tn->key = mask_pfx(key, pos);
- tn->full_children = 0;
- tn->empty_children = 1<<bits;
- }
-@@ -473,10 +465,7 @@ static struct tnode *tnode_new(t_key key
-
- static inline int tnode_full(const struct tnode *tn, const struct rt_trie_node *n)
- {
-- if (n == NULL || IS_LEAF(n))
-- return 0;
--
-- return ((struct tnode *) n)->pos == tn->pos + tn->bits;
-+ return n && IS_TNODE(n) && (n->pos == (tn->pos + tn->bits));
- }
-
- static inline void put_child(struct tnode *tn, int i,
-@@ -514,8 +503,7 @@ static void tnode_put_child_reorg(struct
- else if (!wasfull && isfull)
- tn->full_children++;
-
-- if (n)
-- node_set_parent(n, tn);
-+ node_set_parent(n, tn);
-
- rcu_assign_pointer(tn->child[i], n);
- }
-@@ -523,7 +511,7 @@ static void tnode_put_child_reorg(struct
- #define MAX_WORK 10
- static struct rt_trie_node *resize(struct trie *t, struct tnode *tn)
- {
-- int i;
-+ struct rt_trie_node *n = NULL;
- struct tnode *old_tn;
- int inflate_threshold_use;
- int halve_threshold_use;
-@@ -536,12 +524,11 @@ static struct rt_trie_node *resize(struc
- tn, inflate_threshold, halve_threshold);
-
- /* No children */
-- if (tn->empty_children == tnode_child_length(tn)) {
-- tnode_free_safe(tn);
-- return NULL;
-- }
-+ if (tn->empty_children > (tnode_child_length(tn) - 1))
-+ goto no_children;
-+
- /* One child */
-- if (tn->empty_children == tnode_child_length(tn) - 1)
-+ if (tn->empty_children == (tnode_child_length(tn) - 1))
- goto one_child;
- /*
- * Double as long as the resulting node has a number of
-@@ -607,11 +594,9 @@ static struct rt_trie_node *resize(struc
- *
- */
-
-- check_tnode(tn);
--
- /* Keep root node larger */
-
-- if (!node_parent((struct rt_trie_node *)tn)) {
-+ if (!node_parent(tn)) {
- inflate_threshold_use = inflate_threshold_root;
- halve_threshold_use = halve_threshold_root;
- } else {
-@@ -637,8 +622,6 @@ static struct rt_trie_node *resize(struc
- }
- }
-
-- check_tnode(tn);
--
- /* Return if at least one inflate is run */
- if (max_work != MAX_WORK)
- return (struct rt_trie_node *) tn;
-@@ -666,21 +649,16 @@ static struct rt_trie_node *resize(struc
-
-
- /* Only one child remains */
-- if (tn->empty_children == tnode_child_length(tn) - 1) {
-+ if (tn->empty_children == (tnode_child_length(tn) - 1)) {
-+ unsigned long i;
- one_child:
-- for (i = 0; i < tnode_child_length(tn); i++) {
-- struct rt_trie_node *n;
--
-- n = rtnl_dereference(tn->child[i]);
-- if (!n)
-- continue;
--
-- /* compress one level */
--
-- node_set_parent(n, NULL);
-- tnode_free_safe(tn);
-- return n;
-- }
-+ 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 (struct rt_trie_node *) tn;
- }
-@@ -760,8 +738,7 @@ static struct tnode *inflate(struct trie
-
- /* A leaf or an internal node with skipped bits */
-
-- if (IS_LEAF(node) || ((struct tnode *) node)->pos >
-- tn->pos + tn->bits - 1) {
-+ if (IS_LEAF(node) || (node->pos > (tn->pos + tn->bits - 1))) {
- put_child(tn,
- tkey_extract_bits(node->key, oldtnode->pos, oldtnode->bits + 1),
- node);
-@@ -958,11 +935,9 @@ fib_find_node(struct trie *t, u32 key)
- pos = 0;
- n = rcu_dereference_rtnl(t->trie);
-
-- while (n != NULL && NODE_TYPE(n) == T_TNODE) {
-+ while (n && IS_TNODE(n)) {
- tn = (struct tnode *) n;
-
-- check_tnode(tn);
--
- if (tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) {
- pos = tn->pos + tn->bits;
- n = tnode_get_child_rcu(tn,
-@@ -988,7 +963,7 @@ static void trie_rebalance(struct trie *
-
- key = tn->key;
-
-- while (tn != NULL && (tp = node_parent((struct rt_trie_node *)tn)) != NULL) {
-+ while (tn != NULL && (tp = node_parent(tn)) != NULL) {
- cindex = tkey_extract_bits(key, tp->pos, tp->bits);
- wasfull = tnode_full(tp, tnode_get_child(tp, cindex));
- tn = (struct tnode *)resize(t, tn);
-@@ -996,7 +971,7 @@ static void trie_rebalance(struct trie *
- tnode_put_child_reorg(tp, cindex,
- (struct rt_trie_node *)tn, wasfull);
-
-- tp = node_parent((struct rt_trie_node *) tn);
-+ tp = node_parent(tn);
- if (!tp)
- rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn);
-
-@@ -1048,11 +1023,9 @@ static struct list_head *fib_insert_node
- * If it doesn't, we need to replace it with a T_TNODE.
- */
-
-- while (n != NULL && NODE_TYPE(n) == T_TNODE) {
-+ while (n && IS_TNODE(n)) {
- tn = (struct tnode *) n;
-
-- check_tnode(tn);
--
- if (tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) {
- tp = tn;
- pos = tn->pos + tn->bits;
-@@ -1087,12 +1060,11 @@ static struct list_head *fib_insert_node
- insert_leaf_info(&l->list, li);
- goto done;
- }
-- l = leaf_new();
-+ l = leaf_new(key);
-
- if (!l)
- return NULL;
-
-- l->key = key;
- li = leaf_info_new(plen);
-
- if (!li) {
-@@ -1569,7 +1541,7 @@ backtrace:
- if (chopped_off <= pn->bits) {
- cindex &= ~(1 << (chopped_off-1));
- } else {
-- struct tnode *parent = node_parent_rcu((struct rt_trie_node *) pn);
-+ struct tnode *parent = node_parent_rcu(pn);
- if (!parent)
- goto failed;
-
-@@ -1597,7 +1569,7 @@ EXPORT_SYMBOL_GPL(fib_table_lookup);
- */
- static void trie_leaf_remove(struct trie *t, struct leaf *l)
- {
-- struct tnode *tp = node_parent((struct rt_trie_node *) l);
-+ struct tnode *tp = node_parent(l);
-
- pr_debug("entering trie_leaf_remove(%p)\n", l);
-
-@@ -2374,7 +2346,7 @@ static int fib_trie_seq_show(struct seq_
-
- if (IS_TNODE(n)) {
- struct tnode *tn = (struct tnode *) n;
-- __be32 prf = htonl(mask_pfx(tn->key, tn->pos));
-+ __be32 prf = htonl(tn->key);
-
- seq_indent(seq, iter->depth-1);
- seq_printf(seq, " +-- %pI4/%d %d %d %d\n",