Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 223629
b: refs/heads/master
c: fcbdf09
h: refs/heads/master
i:
  223627: 00b665d
v: v3
  • Loading branch information
Octavian Purdila authored and David S. Miller committed Dec 16, 2010
1 parent 90b8041 commit 5e0e6bf
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2984961c388381c1830f95e1c2dc2137301b1009
refs/heads/master: fcbdf09d9652c8919dcf47072e3ae7dcb4eb98ac
3 changes: 3 additions & 0 deletions trunk/include/net/sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,7 @@ struct proto {
void (*unhash)(struct sock *sk);
void (*rehash)(struct sock *sk);
int (*get_port)(struct sock *sk, unsigned short snum);
void (*clear_sk)(struct sock *sk, int size);

/* Keeping track of sockets in use */
#ifdef CONFIG_PROC_FS
Expand Down Expand Up @@ -852,6 +853,8 @@ static inline void __sk_prot_rehash(struct sock *sk)
sk->sk_prot->hash(sk);
}

void sk_prot_clear_portaddr_nulls(struct sock *sk, int size);

/* About 10 seconds */
#define SOCK_DESTROY_TIME (10*HZ)

Expand Down
47 changes: 35 additions & 12 deletions trunk/net/core/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,36 @@ static void sock_copy(struct sock *nsk, const struct sock *osk)
#endif
}

/*
* caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes
* un-modified. Special care is taken when initializing object to zero.
*/
static inline void sk_prot_clear_nulls(struct sock *sk, int size)
{
if (offsetof(struct sock, sk_node.next) != 0)
memset(sk, 0, offsetof(struct sock, sk_node.next));
memset(&sk->sk_node.pprev, 0,
size - offsetof(struct sock, sk_node.pprev));
}

void sk_prot_clear_portaddr_nulls(struct sock *sk, int size)
{
unsigned long nulls1, nulls2;

nulls1 = offsetof(struct sock, __sk_common.skc_node.next);
nulls2 = offsetof(struct sock, __sk_common.skc_portaddr_node.next);
if (nulls1 > nulls2)
swap(nulls1, nulls2);

if (nulls1 != 0)
memset((char *)sk, 0, nulls1);
memset((char *)sk + nulls1 + sizeof(void *), 0,
nulls2 - nulls1 - sizeof(void *));
memset((char *)sk + nulls2 + sizeof(void *), 0,
size - nulls2 - sizeof(void *));
}
EXPORT_SYMBOL(sk_prot_clear_portaddr_nulls);

static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority,
int family)
{
Expand All @@ -1021,19 +1051,12 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority,
if (!sk)
return sk;
if (priority & __GFP_ZERO) {
/*
* caches using SLAB_DESTROY_BY_RCU should let
* sk_node.next un-modified. Special care is taken
* when initializing object to zero.
*/
if (offsetof(struct sock, sk_node.next) != 0)
memset(sk, 0, offsetof(struct sock, sk_node.next));
memset(&sk->sk_node.pprev, 0,
prot->obj_size - offsetof(struct sock,
sk_node.pprev));
if (prot->clear_sk)
prot->clear_sk(sk, prot->obj_size);
else
sk_prot_clear_nulls(sk, prot->obj_size);
}
}
else
} else
sk = kmalloc(prot->obj_size, priority);

if (sk != NULL) {
Expand Down
1 change: 1 addition & 0 deletions trunk/net/ipv4/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1899,6 +1899,7 @@ struct proto udp_prot = {
.compat_setsockopt = compat_udp_setsockopt,
.compat_getsockopt = compat_udp_getsockopt,
#endif
.clear_sk = sk_prot_clear_portaddr_nulls,
};
EXPORT_SYMBOL(udp_prot);

Expand Down
1 change: 1 addition & 0 deletions trunk/net/ipv4/udplite.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ struct proto udplite_prot = {
.compat_setsockopt = compat_udp_setsockopt,
.compat_getsockopt = compat_udp_getsockopt,
#endif
.clear_sk = sk_prot_clear_portaddr_nulls,
};
EXPORT_SYMBOL(udplite_prot);

Expand Down
1 change: 1 addition & 0 deletions trunk/net/ipv6/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1477,6 +1477,7 @@ struct proto udpv6_prot = {
.compat_setsockopt = compat_udpv6_setsockopt,
.compat_getsockopt = compat_udpv6_getsockopt,
#endif
.clear_sk = sk_prot_clear_portaddr_nulls,
};

static struct inet_protosw udpv6_protosw = {
Expand Down
1 change: 1 addition & 0 deletions trunk/net/ipv6/udplite.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct proto udplitev6_prot = {
.compat_setsockopt = compat_udpv6_setsockopt,
.compat_getsockopt = compat_udpv6_getsockopt,
#endif
.clear_sk = sk_prot_clear_portaddr_nulls,
};

static struct inet_protosw udplite6_protosw = {
Expand Down

0 comments on commit 5e0e6bf

Please sign in to comment.