diff options
author | Eric Dumazet <edumazet@google.com> | 2013-02-07 09:00:34 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-02-08 01:49:49 -0500 |
commit | 87c084a980325d877dc7e388b8f2f26d5d3b4d01 (patch) | |
tree | badbd875581132a7634c6203fcf68f0785449abe /net | |
parent | 586c31f3bf04c290dc0a0de7fc91d20aa9a5ee53 (diff) |
l2tp: dont play with skb->truesize
Andrew Savchenko reported a DNS failure and we diagnosed that
some UDP sockets were unable to send more packets because their
sk_wmem_alloc was corrupted after a while (tx_queue column in
following trace)
$ cat /proc/net/udp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops
...
459: 00000000:0270 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 4507 2 ffff88003d612380 0
466: 00000000:0277 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 4802 2 ffff88003d613180 0
470: 076A070A:007B 00000000:0000 07 FFFF4600:00000000 00:00000000 00000000 123 0 5552 2 ffff880039974380 0
470: 010213AC:007B 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 4986 2 ffff88003dbd3180 0
470: 010013AC:007B 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 4985 2 ffff88003dbd2e00 0
470: 00FCA8C0:007B 00000000:0000 07 FFFFFB00:00000000 00:00000000 00000000 0 0 4984 2 ffff88003dbd2a80 0
...
Playing with skb->truesize is tricky, especially when
skb is attached to a socket, as we can fool memory charging.
Just remove this code, its not worth trying to be ultra
precise in xmit path.
Reported-by: Andrew Savchenko <bircoph@gmail.com>
Tested-by: Andrew Savchenko <bircoph@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: James Chapman <jchapman@katalix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/l2tp/l2tp_core.c | 6 | ||||
-rw-r--r-- | net/l2tp/l2tp_ppp.c | 6 |
2 files changed, 0 insertions, 12 deletions
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 06389d5ff120..2ac884d0e89b 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -1168,8 +1168,6 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len | |||
1168 | struct udphdr *uh; | 1168 | struct udphdr *uh; |
1169 | struct inet_sock *inet; | 1169 | struct inet_sock *inet; |
1170 | __wsum csum; | 1170 | __wsum csum; |
1171 | int old_headroom; | ||
1172 | int new_headroom; | ||
1173 | int headroom; | 1171 | int headroom; |
1174 | int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; | 1172 | int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; |
1175 | int udp_len; | 1173 | int udp_len; |
@@ -1181,16 +1179,12 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len | |||
1181 | */ | 1179 | */ |
1182 | headroom = NET_SKB_PAD + sizeof(struct iphdr) + | 1180 | headroom = NET_SKB_PAD + sizeof(struct iphdr) + |
1183 | uhlen + hdr_len; | 1181 | uhlen + hdr_len; |
1184 | old_headroom = skb_headroom(skb); | ||
1185 | if (skb_cow_head(skb, headroom)) { | 1182 | if (skb_cow_head(skb, headroom)) { |
1186 | kfree_skb(skb); | 1183 | kfree_skb(skb); |
1187 | return NET_XMIT_DROP; | 1184 | return NET_XMIT_DROP; |
1188 | } | 1185 | } |
1189 | 1186 | ||
1190 | new_headroom = skb_headroom(skb); | ||
1191 | skb_orphan(skb); | 1187 | skb_orphan(skb); |
1192 | skb->truesize += new_headroom - old_headroom; | ||
1193 | |||
1194 | /* Setup L2TP header */ | 1188 | /* Setup L2TP header */ |
1195 | session->build_header(session, __skb_push(skb, hdr_len)); | 1189 | session->build_header(session, __skb_push(skb, hdr_len)); |
1196 | 1190 | ||
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 286366ef8930..716605c241f4 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
@@ -388,8 +388,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
388 | struct l2tp_session *session; | 388 | struct l2tp_session *session; |
389 | struct l2tp_tunnel *tunnel; | 389 | struct l2tp_tunnel *tunnel; |
390 | struct pppol2tp_session *ps; | 390 | struct pppol2tp_session *ps; |
391 | int old_headroom; | ||
392 | int new_headroom; | ||
393 | int uhlen, headroom; | 391 | int uhlen, headroom; |
394 | 392 | ||
395 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) | 393 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) |
@@ -408,7 +406,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
408 | if (tunnel == NULL) | 406 | if (tunnel == NULL) |
409 | goto abort_put_sess; | 407 | goto abort_put_sess; |
410 | 408 | ||
411 | old_headroom = skb_headroom(skb); | ||
412 | uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; | 409 | uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; |
413 | headroom = NET_SKB_PAD + | 410 | headroom = NET_SKB_PAD + |
414 | sizeof(struct iphdr) + /* IP header */ | 411 | sizeof(struct iphdr) + /* IP header */ |
@@ -418,9 +415,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
418 | if (skb_cow_head(skb, headroom)) | 415 | if (skb_cow_head(skb, headroom)) |
419 | goto abort_put_sess_tun; | 416 | goto abort_put_sess_tun; |
420 | 417 | ||
421 | new_headroom = skb_headroom(skb); | ||
422 | skb->truesize += new_headroom - old_headroom; | ||
423 | |||
424 | /* Setup PPP header */ | 418 | /* Setup PPP header */ |
425 | __skb_push(skb, sizeof(ppph)); | 419 | __skb_push(skb, sizeof(ppph)); |
426 | skb->data[0] = ppph[0]; | 420 | skb->data[0] = ppph[0]; |