aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_trie.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/fib_trie.c')
-rw-r--r--net/ipv4/fib_trie.c101
1 files changed, 41 insertions, 60 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 63c2fa7b68c4..291bdf50a21f 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -48,7 +48,7 @@
48 * Patrick McHardy <kaber@trash.net> 48 * Patrick McHardy <kaber@trash.net>
49 */ 49 */
50 50
51#define VERSION "0.408" 51#define VERSION "0.409"
52 52
53#include <asm/uaccess.h> 53#include <asm/uaccess.h>
54#include <asm/system.h> 54#include <asm/system.h>
@@ -164,6 +164,14 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn);
164static struct tnode *halve(struct trie *t, struct tnode *tn); 164static struct tnode *halve(struct trie *t, struct tnode *tn);
165/* tnodes to free after resize(); protected by RTNL */ 165/* tnodes to free after resize(); protected by RTNL */
166static struct tnode *tnode_free_head; 166static struct tnode *tnode_free_head;
167static size_t tnode_free_size;
168
169/*
170 * synchronize_rcu after call_rcu for that many pages; it should be especially
171 * useful before resizing the root node with PREEMPT_NONE configs; the value was
172 * obtained experimentally, aiming to avoid visible slowdown.
173 */
174static const int sync_pages = 128;
167 175
168static struct kmem_cache *fn_alias_kmem __read_mostly; 176static struct kmem_cache *fn_alias_kmem __read_mostly;
169static struct kmem_cache *trie_leaf_kmem __read_mostly; 177static struct kmem_cache *trie_leaf_kmem __read_mostly;
@@ -317,8 +325,7 @@ static inline void check_tnode(const struct tnode *tn)
317static const int halve_threshold = 25; 325static const int halve_threshold = 25;
318static const int inflate_threshold = 50; 326static const int inflate_threshold = 50;
319static const int halve_threshold_root = 15; 327static const int halve_threshold_root = 15;
320static const int inflate_threshold_root = 25; 328static const int inflate_threshold_root = 30;
321
322 329
323static void __alias_free_mem(struct rcu_head *head) 330static void __alias_free_mem(struct rcu_head *head)
324{ 331{
@@ -393,6 +400,8 @@ static void tnode_free_safe(struct tnode *tn)
393 BUG_ON(IS_LEAF(tn)); 400 BUG_ON(IS_LEAF(tn));
394 tn->tnode_free = tnode_free_head; 401 tn->tnode_free = tnode_free_head;
395 tnode_free_head = tn; 402 tnode_free_head = tn;
403 tnode_free_size += sizeof(struct tnode) +
404 (sizeof(struct node *) << tn->bits);
396} 405}
397 406
398static void tnode_free_flush(void) 407static void tnode_free_flush(void)
@@ -404,6 +413,11 @@ static void tnode_free_flush(void)
404 tn->tnode_free = NULL; 413 tn->tnode_free = NULL;
405 tnode_free(tn); 414 tnode_free(tn);
406 } 415 }
416
417 if (tnode_free_size >= PAGE_SIZE * sync_pages) {
418 tnode_free_size = 0;
419 synchronize_rcu();
420 }
407} 421}
408 422
409static struct leaf *leaf_new(void) 423static struct leaf *leaf_new(void)
@@ -499,14 +513,14 @@ static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n,
499 rcu_assign_pointer(tn->child[i], n); 513 rcu_assign_pointer(tn->child[i], n);
500} 514}
501 515
516#define MAX_WORK 10
502static struct node *resize(struct trie *t, struct tnode *tn) 517static struct node *resize(struct trie *t, struct tnode *tn)
503{ 518{
504 int i; 519 int i;
505 int err = 0;
506 struct tnode *old_tn; 520 struct tnode *old_tn;
507 int inflate_threshold_use; 521 int inflate_threshold_use;
508 int halve_threshold_use; 522 int halve_threshold_use;
509 int max_resize; 523 int max_work;
510 524
511 if (!tn) 525 if (!tn)
512 return NULL; 526 return NULL;
@@ -521,18 +535,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
521 } 535 }
522 /* One child */ 536 /* One child */
523 if (tn->empty_children == tnode_child_length(tn) - 1) 537 if (tn->empty_children == tnode_child_length(tn) - 1)
524 for (i = 0; i < tnode_child_length(tn); i++) { 538 goto one_child;
525 struct node *n;
526
527 n = tn->child[i];
528 if (!n)
529 continue;
530
531 /* compress one level */
532 node_set_parent(n, NULL);
533 tnode_free_safe(tn);
534 return n;
535 }
536 /* 539 /*
537 * Double as long as the resulting node has a number of 540 * Double as long as the resulting node has a number of
538 * nonempty nodes that are above the threshold. 541 * nonempty nodes that are above the threshold.
@@ -601,14 +604,17 @@ static struct node *resize(struct trie *t, struct tnode *tn)
601 604
602 /* Keep root node larger */ 605 /* Keep root node larger */
603 606
604 if (!tn->parent) 607 if (!node_parent((struct node*) tn)) {
605 inflate_threshold_use = inflate_threshold_root; 608 inflate_threshold_use = inflate_threshold_root;
606 else 609 halve_threshold_use = halve_threshold_root;
610 }
611 else {
607 inflate_threshold_use = inflate_threshold; 612 inflate_threshold_use = inflate_threshold;
613 halve_threshold_use = halve_threshold;
614 }
608 615
609 err = 0; 616 max_work = MAX_WORK;
610 max_resize = 10; 617 while ((tn->full_children > 0 && max_work-- &&
611 while ((tn->full_children > 0 && max_resize-- &&
612 50 * (tn->full_children + tnode_child_length(tn) 618 50 * (tn->full_children + tnode_child_length(tn)
613 - tn->empty_children) 619 - tn->empty_children)
614 >= inflate_threshold_use * tnode_child_length(tn))) { 620 >= inflate_threshold_use * tnode_child_length(tn))) {
@@ -625,35 +631,19 @@ static struct node *resize(struct trie *t, struct tnode *tn)
625 } 631 }
626 } 632 }
627 633
628 if (max_resize < 0) {
629 if (!tn->parent)
630 pr_warning("Fix inflate_threshold_root."
631 " Now=%d size=%d bits\n",
632 inflate_threshold_root, tn->bits);
633 else
634 pr_warning("Fix inflate_threshold."
635 " Now=%d size=%d bits\n",
636 inflate_threshold, tn->bits);
637 }
638
639 check_tnode(tn); 634 check_tnode(tn);
640 635
636 /* Return if at least one inflate is run */
637 if( max_work != MAX_WORK)
638 return (struct node *) tn;
639
641 /* 640 /*
642 * Halve as long as the number of empty children in this 641 * Halve as long as the number of empty children in this
643 * node is above threshold. 642 * node is above threshold.
644 */ 643 */
645 644
646 645 max_work = MAX_WORK;
647 /* Keep root node larger */ 646 while (tn->bits > 1 && max_work-- &&
648
649 if (!tn->parent)
650 halve_threshold_use = halve_threshold_root;
651 else
652 halve_threshold_use = halve_threshold;
653
654 err = 0;
655 max_resize = 10;
656 while (tn->bits > 1 && max_resize-- &&
657 100 * (tnode_child_length(tn) - tn->empty_children) < 647 100 * (tnode_child_length(tn) - tn->empty_children) <
658 halve_threshold_use * tnode_child_length(tn)) { 648 halve_threshold_use * tnode_child_length(tn)) {
659 649
@@ -668,19 +658,10 @@ static struct node *resize(struct trie *t, struct tnode *tn)
668 } 658 }
669 } 659 }
670 660
671 if (max_resize < 0) {
672 if (!tn->parent)
673 pr_warning("Fix halve_threshold_root."
674 " Now=%d size=%d bits\n",
675 halve_threshold_root, tn->bits);
676 else
677 pr_warning("Fix halve_threshold."
678 " Now=%d size=%d bits\n",
679 halve_threshold, tn->bits);
680 }
681 661
682 /* Only one child remains */ 662 /* Only one child remains */
683 if (tn->empty_children == tnode_child_length(tn) - 1) 663 if (tn->empty_children == tnode_child_length(tn) - 1) {
664one_child:
684 for (i = 0; i < tnode_child_length(tn); i++) { 665 for (i = 0; i < tnode_child_length(tn); i++) {
685 struct node *n; 666 struct node *n;
686 667
@@ -694,7 +675,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
694 tnode_free_safe(tn); 675 tnode_free_safe(tn);
695 return n; 676 return n;
696 } 677 }
697 678 }
698 return (struct node *) tn; 679 return (struct node *) tn;
699} 680}
700 681
@@ -1435,7 +1416,7 @@ static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp,
1435 cindex = tkey_extract_bits(mask_pfx(key, current_prefix_length), 1416 cindex = tkey_extract_bits(mask_pfx(key, current_prefix_length),
1436 pos, bits); 1417 pos, bits);
1437 1418
1438 n = tnode_get_child(pn, cindex); 1419 n = tnode_get_child_rcu(pn, cindex);
1439 1420
1440 if (n == NULL) { 1421 if (n == NULL) {
1441#ifdef CONFIG_IP_FIB_TRIE_STATS 1422#ifdef CONFIG_IP_FIB_TRIE_STATS
@@ -1570,7 +1551,7 @@ backtrace:
1570 if (chopped_off <= pn->bits) { 1551 if (chopped_off <= pn->bits) {
1571 cindex &= ~(1 << (chopped_off-1)); 1552 cindex &= ~(1 << (chopped_off-1));
1572 } else { 1553 } else {
1573 struct tnode *parent = node_parent((struct node *) pn); 1554 struct tnode *parent = node_parent_rcu((struct node *) pn);
1574 if (!parent) 1555 if (!parent)
1575 goto failed; 1556 goto failed;
1576 1557
@@ -1783,7 +1764,7 @@ static struct leaf *trie_firstleaf(struct trie *t)
1783static struct leaf *trie_nextleaf(struct leaf *l) 1764static struct leaf *trie_nextleaf(struct leaf *l)
1784{ 1765{
1785 struct node *c = (struct node *) l; 1766 struct node *c = (struct node *) l;
1786 struct tnode *p = node_parent(c); 1767 struct tnode *p = node_parent_rcu(c);
1787 1768
1788 if (!p) 1769 if (!p)
1789 return NULL; /* trie with just one leaf */ 1770 return NULL; /* trie with just one leaf */
@@ -2391,7 +2372,7 @@ static inline const char *rtn_scope(char *buf, size_t len, enum rt_scope_t s)
2391 } 2372 }
2392} 2373}
2393 2374
2394static const char *rtn_type_names[__RTN_MAX] = { 2375static const char *const rtn_type_names[__RTN_MAX] = {
2395 [RTN_UNSPEC] = "UNSPEC", 2376 [RTN_UNSPEC] = "UNSPEC",
2396 [RTN_UNICAST] = "UNICAST", 2377 [RTN_UNICAST] = "UNICAST",
2397 [RTN_LOCAL] = "LOCAL", 2378 [RTN_LOCAL] = "LOCAL",