diff options
author | Julian Anastasov <ja@ssi.bg> | 2013-10-09 02:24:27 -0400 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2013-10-14 21:36:01 -0400 |
commit | 9e4e948a3edafd2b7f4dc14c395e146ffd0d9611 (patch) | |
tree | 2432d5bc712bc0ed0ab9f978807190d093bcd1d3 /include/net/ip_vs.h | |
parent | 120c9794a3ee2f9b1548a1b0b252652e3c134f59 (diff) |
ipvs: avoid rcu_barrier during netns cleanup
commit 578bc3ef1e473a ("ipvs: reorganize dest trash") added
rcu_barrier() on cleanup to wait dest users and schedulers
like LBLC and LBLCR to put their last dest reference.
Using rcu_barrier with many namespaces is problematic.
Trying to fix it by freeing dest with kfree_rcu is not
a solution, RCU callbacks can run in parallel and execution
order is random.
Fix it by creating new function ip_vs_dest_put_and_free()
which is heavier than ip_vs_dest_put(). We will use it just
for schedulers like LBLC, LBLCR that can delay their dest
release.
By default, dests reference is above 0 if they are present in
service and it is 0 when deleted but still in trash list.
Change the dest trash code to use ip_vs_dest_put_and_free(),
so that refcnt -1 can be used for freeing. As result,
such checks remain in slow path and the rcu_barrier() from
netns cleanup can be removed.
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'include/net/ip_vs.h')
-rw-r--r-- | include/net/ip_vs.h | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 1c2e1b9f6b86..cd7275f9c463 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -1442,6 +1442,12 @@ static inline void ip_vs_dest_put(struct ip_vs_dest *dest) | |||
1442 | atomic_dec(&dest->refcnt); | 1442 | atomic_dec(&dest->refcnt); |
1443 | } | 1443 | } |
1444 | 1444 | ||
1445 | static inline void ip_vs_dest_put_and_free(struct ip_vs_dest *dest) | ||
1446 | { | ||
1447 | if (atomic_dec_return(&dest->refcnt) < 0) | ||
1448 | kfree(dest); | ||
1449 | } | ||
1450 | |||
1445 | /* | 1451 | /* |
1446 | * IPVS sync daemon data and function prototypes | 1452 | * IPVS sync daemon data and function prototypes |
1447 | * (from ip_vs_sync.c) | 1453 | * (from ip_vs_sync.c) |