summaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c30
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 */
944static 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
938ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, 954ssize_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
1066do_error: 1082do_error:
1083 tcp_remove_empty_skb(sk, tcp_write_queue_tail(sk));
1067 if (copied) 1084 if (copied)
1068 goto out; 1085 goto out;
1069out_err: 1086out_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
1409do_error:
1410 skb = tcp_write_queue_tail(sk);
1392do_fault: 1411do_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
1403do_error:
1404 if (copied + copied_syn) 1414 if (copied + copied_syn)
1405 goto out; 1415 goto out;
1406out_err: 1416out_err: