diff options
author | David S. Miller <davem@davemloft.net> | 2010-12-17 15:27:22 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-17 15:27:22 -0500 |
commit | b4aa9e05a61b845541fa6f5b1d246976922601f0 (patch) | |
tree | ca94478c3df281ab76a3399f5ba6341ade3f5791 /net/core/sock.c | |
parent | 1dc0f3c54ce1df957f99c17b145488fd03eb1a59 (diff) | |
parent | 4b8fe66300acb2fba8b16d62606e0d30204022fc (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.c | 47 |
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 | */ | ||
1017 | static 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 | |||
1025 | void 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 | } | ||
1041 | EXPORT_SYMBOL(sk_prot_clear_portaddr_nulls); | ||
1042 | |||
1013 | static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, | 1043 | static 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) { |