diff mbox series

[v4,2/2] sock: Move the socket inuse to namespace.

Message ID 1511401885-3686-1-git-send-email-xiangxia.m.yue@gmail.com
State Changes Requested, archived
Delegated to: David Miller
Headers show
Series None | expand

Commit Message

Tonghao Zhang Nov. 23, 2017, 1:51 a.m. UTC
This patch add a member in struct netns_core. And this is
a counter for socket_inuse in the _net_ namespace. The patch
will add/sub counter in the sk_alloc or sk_free. Because socket and
sock is in pair. It's a easy way to maintain the code and help
developer to review. More important, it avoids holding the _net_
namespace again.

Signed-off-by: Martin Zhang <zhangjunweimartin@didichuxing.com>
Signed-off-by: Tonghao Zhang <zhangtonghao@didichuxing.com>
---
v3 --> v4:
1. add noop function for !CONF_PROC_FS case.
2. change the __this_cpu_add to this_cpu_add. This is reported by lkp.
reported at: http://patchwork.ozlabs.org/patch/837424/
---
 include/net/netns/core.h |  1 +
 include/net/sock.h       |  1 +
 net/core/sock.c          | 40 +++++++++++++++++++++++++++++++++++++++-
 net/socket.c             | 13 ++-----------
 4 files changed, 43 insertions(+), 12 deletions(-)

Comments

David Miller Nov. 25, 2017, 2:53 p.m. UTC | #1
From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
Date: Wed, 22 Nov 2017 17:51:25 -0800

> This patch add a member in struct netns_core. And this is
> a counter for socket_inuse in the _net_ namespace. The patch
> will add/sub counter in the sk_alloc or sk_free. Because socket and
> sock is in pair. It's a easy way to maintain the code and help
> developer to review. More important, it avoids holding the _net_
> namespace again.
> 
> Signed-off-by: Martin Zhang <zhangjunweimartin@didichuxing.com>
> Signed-off-by: Tonghao Zhang <zhangtonghao@didichuxing.com>

First, it is extremely unclear why this is better.  You do not explain
the reason at all.

Second:

> @@ -2646,17 +2646,8 @@ static int __init sock_init(void)
>  #ifdef CONFIG_PROC_FS
>  void socket_seq_show(struct seq_file *seq)
>  {
> -	int cpu;
> -	int counter = 0;
> -
> -	for_each_possible_cpu(cpu)
> -	    counter += per_cpu(sockets_in_use, cpu);
> -
> -	/* It can be negative, by the way. 8) */
> -	if (counter < 0)
> -		counter = 0;
> -
> -	seq_printf(seq, "sockets: used %d\n", counter);

You've deleted the only use of "sockets_in_use" but you have not
removed that per-cpu variable and it's maintainence.

But do not even bother fixing this if you cannot explain properly
why these changes are an improvement.  I do not understant it,
and until I do I cannot consider these changes seriously.

Thank you.
Tonghao Zhang Dec. 7, 2017, 4:56 p.m. UTC | #2
On Sat, Nov 25, 2017 at 10:53 PM, David Miller <davem@davemloft.net> wrote:
> From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
> Date: Wed, 22 Nov 2017 17:51:25 -0800
>
>> This patch add a member in struct netns_core. And this is
>> a counter for socket_inuse in the _net_ namespace. The patch
>> will add/sub counter in the sk_alloc or sk_free. Because socket and
>> sock is in pair. It's a easy way to maintain the code and help
>> developer to review. More important, it avoids holding the _net_
>> namespace again.
>>
>> Signed-off-by: Martin Zhang <zhangjunweimartin@didichuxing.com>
>> Signed-off-by: Tonghao Zhang <zhangtonghao@didichuxing.com>
>
> First, it is extremely unclear why this is better.  You do not explain
> the reason at all.
Sorry, I am so later to reply. I send  the v5 and the comment may
explain the reason.

> Second:
>
>> @@ -2646,17 +2646,8 @@ static int __init sock_init(void)
>>  #ifdef CONFIG_PROC_FS
>>  void socket_seq_show(struct seq_file *seq)
>>  {
>> -     int cpu;
>> -     int counter = 0;
>> -
>> -     for_each_possible_cpu(cpu)
>> -         counter += per_cpu(sockets_in_use, cpu);
>> -
>> -     /* It can be negative, by the way. 8) */
>> -     if (counter < 0)
>> -             counter = 0;
>> -
>> -     seq_printf(seq, "sockets: used %d\n", counter);
>
> You've deleted the only use of "sockets_in_use" but you have not
> removed that per-cpu variable and it's maintainence.
So sorry :(

> But do not even bother fixing this if you cannot explain properly
> why these changes are an improvement.  I do not understant it,
> and until I do I cannot consider these changes seriously.
Yes, I should check the patch carefully and add more detail. I may do it better.
The v5 patch may be useful. Thanks so much.

> Thank you.
diff mbox series

Patch

diff --git a/include/net/netns/core.h b/include/net/netns/core.h
index 6490b79..1de41f3 100644
--- a/include/net/netns/core.h
+++ b/include/net/netns/core.h
@@ -11,6 +11,7 @@  struct netns_core {
 	int	sysctl_somaxconn;
 
 	struct prot_inuse __percpu *prot_inuse;
+	int __percpu *sock_inuse;
 };
 
 #endif
diff --git a/include/net/sock.h b/include/net/sock.h
index 6f1be97..169a26f 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1263,6 +1263,7 @@  static inline void sk_sockets_allocated_inc(struct sock *sk)
 /* Called with local bh disabled */
 void sock_prot_inuse_add(struct net *net, struct proto *prot, int inc);
 int sock_prot_inuse_get(struct net *net, struct proto *proto);
+int sock_inuse_get(struct net *net);
 #else
 static inline void sock_prot_inuse_add(struct net *net, struct proto *prot,
 		int inc)
diff --git a/net/core/sock.c b/net/core/sock.c
index b899d86..04bbab1 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -145,6 +145,8 @@ 
 static DEFINE_MUTEX(proto_list_mutex);
 static LIST_HEAD(proto_list);
 
+static void sock_inuse_add(struct net *net, int val);
+
 /**
  * sk_ns_capable - General socket capability test
  * @sk: Socket to use a capability on or through
@@ -1536,6 +1538,7 @@  struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
 		if (likely(sk->sk_net_refcnt))
 			get_net(net);
 		sock_net_set(sk, net);
+		sock_inuse_add(net, 1);
 		refcount_set(&sk->sk_wmem_alloc, 1);
 
 		mem_cgroup_sk_alloc(sk);
@@ -1597,6 +1600,8 @@  void sk_destruct(struct sock *sk)
 
 static void __sk_free(struct sock *sk)
 {
+	sock_inuse_add(sock_net(sk), -1);
+
 	if (unlikely(sock_diag_has_destroy_listeners(sk) && sk->sk_net_refcnt))
 		sock_diag_broadcast_destroy(sk);
 	else
@@ -1665,6 +1670,7 @@  struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
 		newsk->sk_backlog.head	= newsk->sk_backlog.tail = NULL;
 		newsk->sk_backlog.len = 0;
 
+		sock_inuse_add(sock_net(newsk), 1);
 		atomic_set(&newsk->sk_rmem_alloc, 0);
 		/*
 		 * sk_wmem_alloc set to one (see sk_free() and sock_wfree())
@@ -3060,15 +3066,43 @@  int sock_prot_inuse_get(struct net *net, struct proto *prot)
 }
 EXPORT_SYMBOL_GPL(sock_prot_inuse_get);
 
+static void sock_inuse_add(struct net *net, int val)
+{
+	this_cpu_add(*net->core.sock_inuse, val);
+}
+
+int sock_inuse_get(struct net *net)
+{
+	int cpu, res = 0;
+
+	for_each_possible_cpu(cpu)
+		res += *per_cpu_ptr(net->core.sock_inuse, cpu);
+
+	return res >= 0 ? res : 0;
+}
+
+EXPORT_SYMBOL_GPL(sock_inuse_get);
+
 static int __net_init sock_inuse_init_net(struct net *net)
 {
 	net->core.prot_inuse = alloc_percpu(struct prot_inuse);
-	return net->core.prot_inuse ? 0 : -ENOMEM;
+	if (!net->core.prot_inuse)
+		return -ENOMEM;
+
+	net->core.sock_inuse = alloc_percpu(int);
+	if (!net->core.sock_inuse)
+		goto out;
+
+	return 0;
+out:
+	free_percpu(net->core.prot_inuse);
+	return -ENOMEM;
 }
 
 static void __net_exit sock_inuse_exit_net(struct net *net)
 {
 	free_percpu(net->core.prot_inuse);
+	free_percpu(net->core.sock_inuse);
 }
 
 static struct pernet_operations net_inuse_ops = {
@@ -3111,6 +3145,10 @@  static inline void assign_proto_idx(struct proto *prot)
 static inline void release_proto_idx(struct proto *prot)
 {
 }
+
+static void sock_inuse_add(struct net *net, int val)
+{
+}
 #endif
 
 static void req_prot_cleanup(struct request_sock_ops *rsk_prot)
diff --git a/net/socket.c b/net/socket.c
index b085f14..1bdf364 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2646,17 +2646,8 @@  static int __init sock_init(void)
 #ifdef CONFIG_PROC_FS
 void socket_seq_show(struct seq_file *seq)
 {
-	int cpu;
-	int counter = 0;
-
-	for_each_possible_cpu(cpu)
-	    counter += per_cpu(sockets_in_use, cpu);
-
-	/* It can be negative, by the way. 8) */
-	if (counter < 0)
-		counter = 0;
-
-	seq_printf(seq, "sockets: used %d\n", counter);
+	seq_printf(seq, "sockets: used %d\n",
+		   sock_inuse_get(seq->private));
 }
 #endif				/* CONFIG_PROC_FS */