aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
authorDenis V. Lunev <den@openvz.org>2008-07-05 22:06:12 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-05 22:06:12 -0400
commit32cb5b4e035e3d7b52f1e9de87920645a00e5234 (patch)
tree54c26b95e4083e9ed6bb4593a2f940829779979b /net/ipv4/route.c
parente84f84f276473dcc673f360e8ff3203148bdf0e2 (diff)
netns: selective flush of rt_cache
dst cache is marked as expired on the per/namespace basis by previous path. Right now we have to implement selective cache shrinking. This procedure has been ported from older OpenVz codebase. Signed-off-by: Denis V. Lunev <den@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r--net/ipv4/route.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 67c3ed772c27..113cd2512ba7 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -699,6 +699,7 @@ static void rt_do_flush(int process_context)
699{ 699{
700 unsigned int i; 700 unsigned int i;
701 struct rtable *rth, *next; 701 struct rtable *rth, *next;
702 struct rtable * tail;
702 703
703 for (i = 0; i <= rt_hash_mask; i++) { 704 for (i = 0; i <= rt_hash_mask; i++) {
704 if (process_context && need_resched()) 705 if (process_context && need_resched())
@@ -708,11 +709,39 @@ static void rt_do_flush(int process_context)
708 continue; 709 continue;
709 710
710 spin_lock_bh(rt_hash_lock_addr(i)); 711 spin_lock_bh(rt_hash_lock_addr(i));
712#ifdef CONFIG_NET_NS
713 {
714 struct rtable ** prev, * p;
715
716 rth = rt_hash_table[i].chain;
717
718 /* defer releasing the head of the list after spin_unlock */
719 for (tail = rth; tail; tail = tail->u.dst.rt_next)
720 if (!rt_is_expired(tail))
721 break;
722 if (rth != tail)
723 rt_hash_table[i].chain = tail;
724
725 /* call rt_free on entries after the tail requiring flush */
726 prev = &rt_hash_table[i].chain;
727 for (p = *prev; p; p = next) {
728 next = p->u.dst.rt_next;
729 if (!rt_is_expired(p)) {
730 prev = &p->u.dst.rt_next;
731 } else {
732 *prev = next;
733 rt_free(p);
734 }
735 }
736 }
737#else
711 rth = rt_hash_table[i].chain; 738 rth = rt_hash_table[i].chain;
712 rt_hash_table[i].chain = NULL; 739 rt_hash_table[i].chain = NULL;
740 tail = NULL;
741#endif
713 spin_unlock_bh(rt_hash_lock_addr(i)); 742 spin_unlock_bh(rt_hash_lock_addr(i));
714 743
715 for (; rth; rth = next) { 744 for (; rth != tail; rth = next) {
716 next = rth->u.dst.rt_next; 745 next = rth->u.dst.rt_next;
717 rt_free(rth); 746 rt_free(rth);
718 } 747 }