diff options
author | Alexander Duyck <alexander.h.duyck@redhat.com> | 2014-12-31 13:56:18 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-12-31 18:25:54 -0500 |
commit | 98293e8d2f51976d5f790400859a517c0f7cb598 (patch) | |
tree | a2ed6ec3f6be7d4721808474c4a62b3c1c5b6771 /net/ipv4 | |
parent | e9b44019d41a5cf41de43e895a5ed38b19a59b5b (diff) |
fib_trie: Use unsigned long for anything dealing with a shift by bits
This change makes it so that anything that can be shifted by, or compared
to a value shifted by bits is updated to be an unsigned long. This is
mostly a precaution against an insanely huge address space that somehow
starts coming close to the 2^32 root node size which would require
something like 1.5 billion addresses.
I chose unsigned long instead of unsigned long long since I do not believe
it is possible to allocate a 32 bit tnode on a 32 bit system as the memory
consumed would be 16GB + 28B which exceeds the addressible space for any
one process.
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/fib_trie.c | 53 |
1 files changed, 26 insertions, 27 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 9d675486b38c..28a3065470bc 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -146,8 +146,8 @@ struct trie { | |||
146 | #endif | 146 | #endif |
147 | }; | 147 | }; |
148 | 148 | ||
149 | static void tnode_put_child_reorg(struct tnode *tn, int i, struct tnode *n, | 149 | static void tnode_put_child_reorg(struct tnode *tn, unsigned long i, |
150 | int wasfull); | 150 | struct tnode *n, int wasfull); |
151 | static struct tnode *resize(struct trie *t, struct tnode *tn); | 151 | static struct tnode *resize(struct trie *t, struct tnode *tn); |
152 | static struct tnode *inflate(struct trie *t, struct tnode *tn); | 152 | static struct tnode *inflate(struct trie *t, struct tnode *tn); |
153 | static struct tnode *halve(struct trie *t, struct tnode *tn); | 153 | static struct tnode *halve(struct trie *t, struct tnode *tn); |
@@ -183,25 +183,23 @@ static inline void node_set_parent(struct tnode *n, struct tnode *tp) | |||
183 | /* This provides us with the number of children in this node, in the case of a | 183 | /* This provides us with the number of children in this node, in the case of a |
184 | * leaf this will return 0 meaning none of the children are accessible. | 184 | * leaf this will return 0 meaning none of the children are accessible. |
185 | */ | 185 | */ |
186 | static inline int tnode_child_length(const struct tnode *tn) | 186 | static inline unsigned long tnode_child_length(const struct tnode *tn) |
187 | { | 187 | { |
188 | return (1ul << tn->bits) & ~(1ul); | 188 | return (1ul << tn->bits) & ~(1ul); |
189 | } | 189 | } |
190 | 190 | ||
191 | /* | 191 | /* caller must hold RTNL */ |
192 | * caller must hold RTNL | 192 | static inline struct tnode *tnode_get_child(const struct tnode *tn, |
193 | */ | 193 | unsigned long i) |
194 | static inline struct tnode *tnode_get_child(const struct tnode *tn, unsigned int i) | ||
195 | { | 194 | { |
196 | BUG_ON(i >= tnode_child_length(tn)); | 195 | BUG_ON(i >= tnode_child_length(tn)); |
197 | 196 | ||
198 | return rtnl_dereference(tn->child[i]); | 197 | return rtnl_dereference(tn->child[i]); |
199 | } | 198 | } |
200 | 199 | ||
201 | /* | 200 | /* caller must hold RCU read lock or RTNL */ |
202 | * caller must hold RCU read lock or RTNL | 201 | static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, |
203 | */ | 202 | unsigned long i) |
204 | static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, unsigned int i) | ||
205 | { | 203 | { |
206 | BUG_ON(i >= tnode_child_length(tn)); | 204 | BUG_ON(i >= tnode_child_length(tn)); |
207 | 205 | ||
@@ -400,7 +398,7 @@ static inline int tnode_full(const struct tnode *tn, const struct tnode *n) | |||
400 | return n && ((n->pos + n->bits) == tn->pos) && IS_TNODE(n); | 398 | return n && ((n->pos + n->bits) == tn->pos) && IS_TNODE(n); |
401 | } | 399 | } |
402 | 400 | ||
403 | static inline void put_child(struct tnode *tn, int i, | 401 | static inline void put_child(struct tnode *tn, unsigned long i, |
404 | struct tnode *n) | 402 | struct tnode *n) |
405 | { | 403 | { |
406 | tnode_put_child_reorg(tn, i, n, -1); | 404 | tnode_put_child_reorg(tn, i, n, -1); |
@@ -411,13 +409,13 @@ static inline void put_child(struct tnode *tn, int i, | |||
411 | * Update the value of full_children and empty_children. | 409 | * Update the value of full_children and empty_children. |
412 | */ | 410 | */ |
413 | 411 | ||
414 | static void tnode_put_child_reorg(struct tnode *tn, int i, struct tnode *n, | 412 | static void tnode_put_child_reorg(struct tnode *tn, unsigned long i, |
415 | int wasfull) | 413 | struct tnode *n, int wasfull) |
416 | { | 414 | { |
417 | struct tnode *chi = rtnl_dereference(tn->child[i]); | 415 | struct tnode *chi = rtnl_dereference(tn->child[i]); |
418 | int isfull; | 416 | int isfull; |
419 | 417 | ||
420 | BUG_ON(i >= 1<<tn->bits); | 418 | BUG_ON(i >= tnode_child_length(tn)); |
421 | 419 | ||
422 | /* update emptyChildren */ | 420 | /* update emptyChildren */ |
423 | if (n == NULL && chi != NULL) | 421 | if (n == NULL && chi != NULL) |
@@ -607,10 +605,10 @@ no_children: | |||
607 | static void tnode_clean_free(struct tnode *tn) | 605 | static void tnode_clean_free(struct tnode *tn) |
608 | { | 606 | { |
609 | struct tnode *tofree; | 607 | struct tnode *tofree; |
610 | int i; | 608 | unsigned long i; |
611 | 609 | ||
612 | for (i = 0; i < tnode_child_length(tn); i++) { | 610 | for (i = 0; i < tnode_child_length(tn); i++) { |
613 | tofree = rtnl_dereference(tn->child[i]); | 611 | tofree = tnode_get_child(tn, i); |
614 | if (tofree) | 612 | if (tofree) |
615 | node_free(tofree); | 613 | node_free(tofree); |
616 | } | 614 | } |
@@ -619,10 +617,10 @@ static void tnode_clean_free(struct tnode *tn) | |||
619 | 617 | ||
620 | static struct tnode *inflate(struct trie *t, struct tnode *oldtnode) | 618 | static struct tnode *inflate(struct trie *t, struct tnode *oldtnode) |
621 | { | 619 | { |
622 | int olen = tnode_child_length(oldtnode); | 620 | unsigned long olen = tnode_child_length(oldtnode); |
623 | struct tnode *tn; | 621 | struct tnode *tn; |
622 | unsigned long i; | ||
624 | t_key m; | 623 | t_key m; |
625 | int i; | ||
626 | 624 | ||
627 | pr_debug("In inflate\n"); | 625 | pr_debug("In inflate\n"); |
628 | 626 | ||
@@ -664,7 +662,7 @@ static struct tnode *inflate(struct trie *t, struct tnode *oldtnode) | |||
664 | for (i = 0; i < olen; i++) { | 662 | for (i = 0; i < olen; i++) { |
665 | struct tnode *inode = tnode_get_child(oldtnode, i); | 663 | struct tnode *inode = tnode_get_child(oldtnode, i); |
666 | struct tnode *left, *right; | 664 | struct tnode *left, *right; |
667 | int size, j; | 665 | unsigned long size, j; |
668 | 666 | ||
669 | /* An empty child */ | 667 | /* An empty child */ |
670 | if (inode == NULL) | 668 | if (inode == NULL) |
@@ -737,7 +735,7 @@ nomem: | |||
737 | 735 | ||
738 | static struct tnode *halve(struct trie *t, struct tnode *oldtnode) | 736 | static struct tnode *halve(struct trie *t, struct tnode *oldtnode) |
739 | { | 737 | { |
740 | int olen = tnode_child_length(oldtnode); | 738 | unsigned long olen = tnode_child_length(oldtnode); |
741 | struct tnode *tn, *left, *right; | 739 | struct tnode *tn, *left, *right; |
742 | int i; | 740 | int i; |
743 | 741 | ||
@@ -1532,9 +1530,9 @@ static int trie_flush_leaf(struct tnode *l) | |||
1532 | static struct tnode *leaf_walk_rcu(struct tnode *p, struct tnode *c) | 1530 | static struct tnode *leaf_walk_rcu(struct tnode *p, struct tnode *c) |
1533 | { | 1531 | { |
1534 | do { | 1532 | do { |
1535 | t_key idx = c ? idx = get_index(c->key, p) + 1 : 0; | 1533 | unsigned long idx = c ? idx = get_index(c->key, p) + 1 : 0; |
1536 | 1534 | ||
1537 | while (idx < 1u << p->bits) { | 1535 | while (idx < tnode_child_length(p)) { |
1538 | c = tnode_get_child_rcu(p, idx++); | 1536 | c = tnode_get_child_rcu(p, idx++); |
1539 | if (!c) | 1537 | if (!c) |
1540 | continue; | 1538 | continue; |
@@ -1786,8 +1784,8 @@ struct fib_trie_iter { | |||
1786 | 1784 | ||
1787 | static struct tnode *fib_trie_get_next(struct fib_trie_iter *iter) | 1785 | static struct tnode *fib_trie_get_next(struct fib_trie_iter *iter) |
1788 | { | 1786 | { |
1787 | unsigned long cindex = iter->index; | ||
1789 | struct tnode *tn = iter->tnode; | 1788 | struct tnode *tn = iter->tnode; |
1790 | unsigned int cindex = iter->index; | ||
1791 | struct tnode *p; | 1789 | struct tnode *p; |
1792 | 1790 | ||
1793 | /* A single entry routing table */ | 1791 | /* A single entry routing table */ |
@@ -1797,7 +1795,7 @@ static struct tnode *fib_trie_get_next(struct fib_trie_iter *iter) | |||
1797 | pr_debug("get_next iter={node=%p index=%d depth=%d}\n", | 1795 | pr_debug("get_next iter={node=%p index=%d depth=%d}\n", |
1798 | iter->tnode, iter->index, iter->depth); | 1796 | iter->tnode, iter->index, iter->depth); |
1799 | rescan: | 1797 | rescan: |
1800 | while (cindex < (1<<tn->bits)) { | 1798 | while (cindex < tnode_child_length(tn)) { |
1801 | struct tnode *n = tnode_get_child_rcu(tn, cindex); | 1799 | struct tnode *n = tnode_get_child_rcu(tn, cindex); |
1802 | 1800 | ||
1803 | if (n) { | 1801 | if (n) { |
@@ -1874,15 +1872,16 @@ static void trie_collect_stats(struct trie *t, struct trie_stat *s) | |||
1874 | hlist_for_each_entry_rcu(li, &n->list, hlist) | 1872 | hlist_for_each_entry_rcu(li, &n->list, hlist) |
1875 | ++s->prefixes; | 1873 | ++s->prefixes; |
1876 | } else { | 1874 | } else { |
1877 | int i; | 1875 | unsigned long i; |
1878 | 1876 | ||
1879 | s->tnodes++; | 1877 | s->tnodes++; |
1880 | if (n->bits < MAX_STAT_DEPTH) | 1878 | if (n->bits < MAX_STAT_DEPTH) |
1881 | s->nodesizes[n->bits]++; | 1879 | s->nodesizes[n->bits]++; |
1882 | 1880 | ||
1883 | for (i = 0; i < tnode_child_length(n); i++) | 1881 | for (i = 0; i < tnode_child_length(n); i++) { |
1884 | if (!rcu_access_pointer(n->child[i])) | 1882 | if (!rcu_access_pointer(n->child[i])) |
1885 | s->nullpointers++; | 1883 | s->nullpointers++; |
1884 | } | ||
1886 | } | 1885 | } |
1887 | } | 1886 | } |
1888 | rcu_read_unlock(); | 1887 | rcu_read_unlock(); |