diff options
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r-- | net/ipv4/tcp.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 051ef10374f6..94df48bcecc2 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -935,6 +935,22 @@ static int tcp_send_mss(struct sock *sk, int *size_goal, int flags) | |||
935 | return mss_now; | 935 | return mss_now; |
936 | } | 936 | } |
937 | 937 | ||
938 | /* In some cases, both sendpage() and sendmsg() could have added | ||
939 | * an skb to the write queue, but failed adding payload on it. | ||
940 | * We need to remove it to consume less memory, but more | ||
941 | * importantly be able to generate EPOLLOUT for Edge Trigger epoll() | ||
942 | * users. | ||
943 | */ | ||
944 | static void tcp_remove_empty_skb(struct sock *sk, struct sk_buff *skb) | ||
945 | { | ||
946 | if (skb && !skb->len) { | ||
947 | tcp_unlink_write_queue(skb, sk); | ||
948 | if (tcp_write_queue_empty(sk)) | ||
949 | tcp_chrono_stop(sk, TCP_CHRONO_BUSY); | ||
950 | sk_wmem_free_skb(sk, skb); | ||
951 | } | ||
952 | } | ||
953 | |||
938 | ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, | 954 | ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, |
939 | size_t size, int flags) | 955 | size_t size, int flags) |
940 | { | 956 | { |
@@ -1064,6 +1080,7 @@ out: | |||
1064 | return copied; | 1080 | return copied; |
1065 | 1081 | ||
1066 | do_error: | 1082 | do_error: |
1083 | tcp_remove_empty_skb(sk, tcp_write_queue_tail(sk)); | ||
1067 | if (copied) | 1084 | if (copied) |
1068 | goto out; | 1085 | goto out; |
1069 | out_err: | 1086 | out_err: |
@@ -1389,18 +1406,11 @@ out_nopush: | |||
1389 | sock_zerocopy_put(uarg); | 1406 | sock_zerocopy_put(uarg); |
1390 | return copied + copied_syn; | 1407 | return copied + copied_syn; |
1391 | 1408 | ||
1409 | do_error: | ||
1410 | skb = tcp_write_queue_tail(sk); | ||
1392 | do_fault: | 1411 | do_fault: |
1393 | if (!skb->len) { | 1412 | tcp_remove_empty_skb(sk, skb); |
1394 | tcp_unlink_write_queue(skb, sk); | ||
1395 | /* It is the one place in all of TCP, except connection | ||
1396 | * reset, where we can be unlinking the send_head. | ||
1397 | */ | ||
1398 | if (tcp_write_queue_empty(sk)) | ||
1399 | tcp_chrono_stop(sk, TCP_CHRONO_BUSY); | ||
1400 | sk_wmem_free_skb(sk, skb); | ||
1401 | } | ||
1402 | 1413 | ||
1403 | do_error: | ||
1404 | if (copied + copied_syn) | 1414 | if (copied + copied_syn) |
1405 | goto out; | 1415 | goto out; |
1406 | out_err: | 1416 | out_err: |