Implement exit_batch() method to dismantle more ipvs netns
per round.
Tested:
$ cat add_del_unshare.sh
#!/bin/bash
for i in `seq 1 100`
do
(for j in `seq 1 40` ; do unshare -n ipvsadm -A -t 172.16.$i.$j:80 >/dev/null ; done) &
done
wait; grep net_namespace /proc/slabinfo
Befor patch:
$ time sh add_del_unshare.sh
net_namespace 4020 4020 4736 6 8 : tunables 0 0 0 : slabdata 670 670 0
real 0m8.086s
user 0m2.025s
sys 0m36.956s
After patch:
$ time sh add_del_unshare.sh
net_namespace 4020 4020 4736 6 8 : tunables 0 0 0 : slabdata 670 670 0
real 0m7.623s
user 0m2.003s
sys 0m32.935s
Haishuang Yan (2):
ipvs: batch __ip_vs_cleanup
ipvs: batch __ip_vs_dev_cleanup
include/net/ip_vs.h | 2 +-
net/netfilter/ipvs/ip_vs_core.c | 47 ++++++++++++++++++++++++-----------------
net/netfilter/ipvs/ip_vs_ctl.c | 12 ++++++++---
3 files changed, 38 insertions(+), 23 deletions(-)
--
1.8.3.1
It's better to batch __ip_vs_cleanup to speedup ipvs
connections dismantle.
Signed-off-by: Haishuang Yan <[email protected]>
---
v2: remove unused pointer list
---
include/net/ip_vs.h | 2 +-
net/netfilter/ipvs/ip_vs_core.c | 28 ++++++++++++++++------------
net/netfilter/ipvs/ip_vs_ctl.c | 12 +++++++++---
3 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 3759167..93e7a25 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -1324,7 +1324,7 @@ static inline void ip_vs_control_del(struct ip_vs_conn *cp)
void ip_vs_control_net_cleanup(struct netns_ipvs *ipvs);
void ip_vs_estimator_net_cleanup(struct netns_ipvs *ipvs);
void ip_vs_sync_net_cleanup(struct netns_ipvs *ipvs);
-void ip_vs_service_net_cleanup(struct netns_ipvs *ipvs);
+void ip_vs_service_nets_cleanup(struct list_head *net_list);
/* IPVS application functions
* (from ip_vs_app.c)
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 8b80ab7..93cfb47 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -2402,18 +2402,22 @@ static int __net_init __ip_vs_init(struct net *net)
return -ENOMEM;
}
-static void __net_exit __ip_vs_cleanup(struct net *net)
+static void __net_exit __ip_vs_cleanup_batch(struct list_head *net_list)
{
- struct netns_ipvs *ipvs = net_ipvs(net);
-
- ip_vs_service_net_cleanup(ipvs); /* ip_vs_flush() with locks */
- ip_vs_conn_net_cleanup(ipvs);
- ip_vs_app_net_cleanup(ipvs);
- ip_vs_protocol_net_cleanup(ipvs);
- ip_vs_control_net_cleanup(ipvs);
- ip_vs_estimator_net_cleanup(ipvs);
- IP_VS_DBG(2, "ipvs netns %d released\n", ipvs->gen);
- net->ipvs = NULL;
+ struct netns_ipvs *ipvs;
+ struct net *net;
+
+ ip_vs_service_nets_cleanup(net_list); /* ip_vs_flush() with locks */
+ list_for_each_entry(net, net_list, exit_list) {
+ ipvs = net_ipvs(net);
+ ip_vs_conn_net_cleanup(ipvs);
+ ip_vs_app_net_cleanup(ipvs);
+ ip_vs_protocol_net_cleanup(ipvs);
+ ip_vs_control_net_cleanup(ipvs);
+ ip_vs_estimator_net_cleanup(ipvs);
+ IP_VS_DBG(2, "ipvs netns %d released\n", ipvs->gen);
+ net->ipvs = NULL;
+ }
}
static int __net_init __ip_vs_dev_init(struct net *net)
@@ -2442,7 +2446,7 @@ static void __net_exit __ip_vs_dev_cleanup(struct net *net)
static struct pernet_operations ipvs_core_ops = {
.init = __ip_vs_init,
- .exit = __ip_vs_cleanup,
+ .exit_batch = __ip_vs_cleanup_batch,
.id = &ip_vs_net_id,
.size = sizeof(struct netns_ipvs),
};
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 8b48e7c..153c77b 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -1607,14 +1607,20 @@ static int ip_vs_flush(struct netns_ipvs *ipvs, bool cleanup)
/*
* Delete service by {netns} in the service table.
- * Called by __ip_vs_cleanup()
+ * Called by __ip_vs_batch_cleanup()
*/
-void ip_vs_service_net_cleanup(struct netns_ipvs *ipvs)
+void ip_vs_service_nets_cleanup(struct list_head *net_list)
{
+ struct netns_ipvs *ipvs;
+ struct net *net;
+
EnterFunction(2);
/* Check for "full" addressed entries */
mutex_lock(&__ip_vs_mutex);
- ip_vs_flush(ipvs, true);
+ list_for_each_entry(net, net_list, exit_list) {
+ ipvs = net_ipvs(net);
+ ip_vs_flush(ipvs, true);
+ }
mutex_unlock(&__ip_vs_mutex);
LeaveFunction(2);
}
--
1.8.3.1
It's better to batch __ip_vs_cleanup to speedup ipvs
devices dismantle.
Signed-off-by: Haishuang Yan <[email protected]>
---
v2: remove unused pointer list
---
net/netfilter/ipvs/ip_vs_core.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 93cfb47..512259f 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -2433,14 +2433,19 @@ static int __net_init __ip_vs_dev_init(struct net *net)
return ret;
}
-static void __net_exit __ip_vs_dev_cleanup(struct net *net)
+static void __net_exit __ip_vs_dev_cleanup_batch(struct list_head *net_list)
{
- struct netns_ipvs *ipvs = net_ipvs(net);
+ struct netns_ipvs *ipvs;
+ struct net *net;
+
EnterFunction(2);
- nf_unregister_net_hooks(net, ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
- ipvs->enable = 0; /* Disable packet reception */
- smp_wmb();
- ip_vs_sync_net_cleanup(ipvs);
+ list_for_each_entry(net, net_list, exit_list) {
+ ipvs = net_ipvs(net);
+ nf_unregister_net_hooks(net, ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
+ ipvs->enable = 0; /* Disable packet reception */
+ smp_wmb();
+ ip_vs_sync_net_cleanup(ipvs);
+ }
LeaveFunction(2);
}
@@ -2453,7 +2458,7 @@ static void __net_exit __ip_vs_dev_cleanup(struct net *net)
static struct pernet_operations ipvs_core_dev_ops = {
.init = __ip_vs_dev_init,
- .exit = __ip_vs_dev_cleanup,
+ .exit_batch = __ip_vs_dev_cleanup_batch,
};
/*
--
1.8.3.1
Hello,
On Fri, 27 Sep 2019, Haishuang Yan wrote:
> Implement exit_batch() method to dismantle more ipvs netns
> per round.
>
> Tested:
> $ cat add_del_unshare.sh
> #!/bin/bash
>
> for i in `seq 1 100`
> do
> (for j in `seq 1 40` ; do unshare -n ipvsadm -A -t 172.16.$i.$j:80 >/dev/null ; done) &
> done
> wait; grep net_namespace /proc/slabinfo
>
> Befor patch:
> $ time sh add_del_unshare.sh
> net_namespace 4020 4020 4736 6 8 : tunables 0 0 0 : slabdata 670 670 0
>
> real 0m8.086s
> user 0m2.025s
> sys 0m36.956s
>
> After patch:
> $ time sh add_del_unshare.sh
> net_namespace 4020 4020 4736 6 8 : tunables 0 0 0 : slabdata 670 670 0
>
> real 0m7.623s
> user 0m2.003s
> sys 0m32.935s
>
> Haishuang Yan (2):
> ipvs: batch __ip_vs_cleanup
> ipvs: batch __ip_vs_dev_cleanup
>
> include/net/ip_vs.h | 2 +-
> net/netfilter/ipvs/ip_vs_core.c | 47 ++++++++++++++++++++++++-----------------
> net/netfilter/ipvs/ip_vs_ctl.c | 12 ++++++++---
> 3 files changed, 38 insertions(+), 23 deletions(-)
Both patches in v2 look good to me, thanks!
Acked-by: Julian Anastasov <[email protected]>
This is for the -next kernels...
Regards
--
Julian Anastasov <[email protected]>
On Mon, Sep 30, 2019 at 10:08:23PM +0300, Julian Anastasov wrote:
>
> Hello,
>
> On Fri, 27 Sep 2019, Haishuang Yan wrote:
>
> > Implement exit_batch() method to dismantle more ipvs netns
> > per round.
> >
> > Tested:
> > $ cat add_del_unshare.sh
> > #!/bin/bash
> >
> > for i in `seq 1 100`
> > do
> > (for j in `seq 1 40` ; do unshare -n ipvsadm -A -t 172.16.$i.$j:80 >/dev/null ; done) &
> > done
> > wait; grep net_namespace /proc/slabinfo
> >
> > Befor patch:
> > $ time sh add_del_unshare.sh
> > net_namespace 4020 4020 4736 6 8 : tunables 0 0 0 : slabdata 670 670 0
> >
> > real 0m8.086s
> > user 0m2.025s
> > sys 0m36.956s
> >
> > After patch:
> > $ time sh add_del_unshare.sh
> > net_namespace 4020 4020 4736 6 8 : tunables 0 0 0 : slabdata 670 670 0
> >
> > real 0m7.623s
> > user 0m2.003s
> > sys 0m32.935s
> >
> > Haishuang Yan (2):
> > ipvs: batch __ip_vs_cleanup
> > ipvs: batch __ip_vs_dev_cleanup
> >
> > include/net/ip_vs.h | 2 +-
> > net/netfilter/ipvs/ip_vs_core.c | 47 ++++++++++++++++++++++++-----------------
> > net/netfilter/ipvs/ip_vs_ctl.c | 12 ++++++++---
> > 3 files changed, 38 insertions(+), 23 deletions(-)
>
> Both patches in v2 look good to me, thanks!
>
> Acked-by: Julian Anastasov <[email protected]>
>
> This is for the -next kernels...
Thanks, applied to ipvs-next.