aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/sock.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-12-17 15:27:22 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-17 15:27:22 -0500
commitb4aa9e05a61b845541fa6f5b1d246976922601f0 (patch)
treeca94478c3df281ab76a3399f5ba6341ade3f5791 /net/core/sock.c
parent1dc0f3c54ce1df957f99c17b145488fd03eb1a59 (diff)
parent4b8fe66300acb2fba8b16d62606e0d30204022fc (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/bnx2x/bnx2x.h drivers/net/wireless/iwlwifi/iwl-1000.c drivers/net/wireless/iwlwifi/iwl-6000.c drivers/net/wireless/iwlwifi/iwl-core.h drivers/vhost/vhost.c
Diffstat (limited to 'net/core/sock.c')
-rw-r--r--net/core/sock.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/net/core/sock.c b/net/core/sock.c
index bcdb6ff6e621..a6b9e8061f34 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1010,6 +1010,36 @@ static void sock_copy(struct sock *nsk, const struct sock *osk)
1010#endif 1010#endif
1011} 1011}
1012 1012
1013/*
1014 * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes
1015 * un-modified. Special care is taken when initializing object to zero.
1016 */
1017static inline void sk_prot_clear_nulls(struct sock *sk, int size)
1018{
1019 if (offsetof(struct sock, sk_node.next) != 0)
1020 memset(sk, 0, offsetof(struct sock, sk_node.next));
1021 memset(&sk->sk_node.pprev, 0,
1022 size - offsetof(struct sock, sk_node.pprev));
1023}
1024
1025void sk_prot_clear_portaddr_nulls(struct sock *sk, int size)
1026{
1027 unsigned long nulls1, nulls2;
1028
1029 nulls1 = offsetof(struct sock, __sk_common.skc_node.next);
1030 nulls2 = offsetof(struct sock, __sk_common.skc_portaddr_node.next);
1031 if (nulls1 > nulls2)
1032 swap(nulls1, nulls2);
1033
1034 if (nulls1 != 0)
1035 memset((char *)sk, 0, nulls1);
1036 memset((char *)sk + nulls1 + sizeof(void *), 0,
1037 nulls2 - nulls1 - sizeof(void *));
1038 memset((char *)sk + nulls2 + sizeof(void *), 0,
1039 size - nulls2 - sizeof(void *));
1040}
1041EXPORT_SYMBOL(sk_prot_clear_portaddr_nulls);
1042
1013static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, 1043static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority,
1014 int family) 1044 int family)
1015{ 1045{
@@ -1022,19 +1052,12 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority,
1022 if (!sk) 1052 if (!sk)
1023 return sk; 1053 return sk;
1024 if (priority & __GFP_ZERO) { 1054 if (priority & __GFP_ZERO) {
1025 /* 1055 if (prot->clear_sk)
1026 * caches using SLAB_DESTROY_BY_RCU should let 1056 prot->clear_sk(sk, prot->obj_size);
1027 * sk_node.next un-modified. Special care is taken 1057 else
1028 * when initializing object to zero. 1058 sk_prot_clear_nulls(sk, prot->obj_size);
1029 */
1030 if (offsetof(struct sock, sk_node.next) != 0)
1031 memset(sk, 0, offsetof(struct sock, sk_node.next));
1032 memset(&sk->sk_node.pprev, 0,
1033 prot->obj_size - offsetof(struct sock,
1034 sk_node.pprev));
1035 } 1059 }
1036 } 1060 } else
1037 else
1038 sk = kmalloc(prot->obj_size, priority); 1061 sk = kmalloc(prot->obj_size, priority);
1039 1062
1040 if (sk != NULL) { 1063 if (sk != NULL) {