From 1a89ed0231222eded0994f1cc6921c3a90dc7f08 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Sat, 5 Jul 2008 19:06:12 -0700 Subject: [PATCH] --- yaml --- r: 103227 b: refs/heads/master c: 32cb5b4e035e3d7b52f1e9de87920645a00e5234 h: refs/heads/master i: 103225: ea5e150b97b8258a70871fcefdf702016cb9fec7 103223: 47b97ed330b97fcb2947dfda887e7c000e83b6b3 v: v3 --- [refs] | 2 +- trunk/net/ipv4/route.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 087dc152ae45..6e282b2e5bf0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e84f84f276473dcc673f360e8ff3203148bdf0e2 +refs/heads/master: 32cb5b4e035e3d7b52f1e9de87920645a00e5234 diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index 67c3ed772c27..113cd2512ba7 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -699,6 +699,7 @@ static void rt_do_flush(int process_context) { unsigned int i; struct rtable *rth, *next; + struct rtable * tail; for (i = 0; i <= rt_hash_mask; i++) { if (process_context && need_resched()) @@ -708,11 +709,39 @@ static void rt_do_flush(int process_context) continue; spin_lock_bh(rt_hash_lock_addr(i)); +#ifdef CONFIG_NET_NS + { + struct rtable ** prev, * p; + + rth = rt_hash_table[i].chain; + + /* defer releasing the head of the list after spin_unlock */ + for (tail = rth; tail; tail = tail->u.dst.rt_next) + if (!rt_is_expired(tail)) + break; + if (rth != tail) + rt_hash_table[i].chain = tail; + + /* call rt_free on entries after the tail requiring flush */ + prev = &rt_hash_table[i].chain; + for (p = *prev; p; p = next) { + next = p->u.dst.rt_next; + if (!rt_is_expired(p)) { + prev = &p->u.dst.rt_next; + } else { + *prev = next; + rt_free(p); + } + } + } +#else rth = rt_hash_table[i].chain; rt_hash_table[i].chain = NULL; + tail = NULL; +#endif spin_unlock_bh(rt_hash_lock_addr(i)); - for (; rth; rth = next) { + for (; rth != tail; rth = next) { next = rth->u.dst.rt_next; rt_free(rth); }