diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2015-05-08 22:10:31 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-05-11 10:50:18 -0400 |
commit | 26abe14379f8e2fa3fd1bcf97c9a7ad9364886fe (patch) | |
tree | e2161c09531299ce4bfbeb1506c420b9f8db7fc2 /net/core/sock.c | |
parent | 11aa9c28b4209242a9de0a661a7b3405adb568a0 (diff) |
net: Modify sk_alloc to not reference count the netns of kernel sockets.
Now that sk_alloc knows when a kernel socket is being allocated modify
it to not reference count the network namespace of kernel sockets.
Keep track of if a socket needs reference counting by adding a flag to
struct sock called sk_net_refcnt.
Update all of the callers of sock_create_kern to stop using
sk_change_net and sk_release_kernel as those hacks are no longer
needed, to avoid reference counting a kernel socket.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/sock.c')
-rw-r--r-- | net/core/sock.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index cbc3789b830c..9e8968e9ebeb 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1412,7 +1412,10 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, | |||
1412 | */ | 1412 | */ |
1413 | sk->sk_prot = sk->sk_prot_creator = prot; | 1413 | sk->sk_prot = sk->sk_prot_creator = prot; |
1414 | sock_lock_init(sk); | 1414 | sock_lock_init(sk); |
1415 | sock_net_set(sk, get_net(net)); | 1415 | sk->sk_net_refcnt = kern ? 0 : 1; |
1416 | if (likely(sk->sk_net_refcnt)) | ||
1417 | get_net(net); | ||
1418 | sock_net_set(sk, net); | ||
1416 | atomic_set(&sk->sk_wmem_alloc, 1); | 1419 | atomic_set(&sk->sk_wmem_alloc, 1); |
1417 | 1420 | ||
1418 | sock_update_classid(sk); | 1421 | sock_update_classid(sk); |
@@ -1446,7 +1449,8 @@ static void __sk_free(struct sock *sk) | |||
1446 | if (sk->sk_peer_cred) | 1449 | if (sk->sk_peer_cred) |
1447 | put_cred(sk->sk_peer_cred); | 1450 | put_cred(sk->sk_peer_cred); |
1448 | put_pid(sk->sk_peer_pid); | 1451 | put_pid(sk->sk_peer_pid); |
1449 | put_net(sock_net(sk)); | 1452 | if (likely(sk->sk_net_refcnt)) |
1453 | put_net(sock_net(sk)); | ||
1450 | sk_prot_free(sk->sk_prot_creator, sk); | 1454 | sk_prot_free(sk->sk_prot_creator, sk); |
1451 | } | 1455 | } |
1452 | 1456 | ||