diff options
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r-- | net/ipv4/tcp.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 776905899ac0..61082065b26a 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 | { |
@@ -984,6 +1000,9 @@ new_segment: | |||
984 | if (!skb) | 1000 | if (!skb) |
985 | goto wait_for_memory; | 1001 | goto wait_for_memory; |
986 | 1002 | ||
1003 | #ifdef CONFIG_TLS_DEVICE | ||
1004 | skb->decrypted = !!(flags & MSG_SENDPAGE_DECRYPTED); | ||
1005 | #endif | ||
987 | skb_entail(sk, skb); | 1006 | skb_entail(sk, skb); |
988 | copy = size_goal; | 1007 | copy = size_goal; |
989 | } | 1008 | } |
@@ -1061,6 +1080,7 @@ out: | |||
1061 | return copied; | 1080 | return copied; |
1062 | 1081 | ||
1063 | do_error: | 1082 | do_error: |
1083 | tcp_remove_empty_skb(sk, tcp_write_queue_tail(sk)); | ||
1064 | if (copied) | 1084 | if (copied) |
1065 | goto out; | 1085 | goto out; |
1066 | out_err: | 1086 | out_err: |
@@ -1385,18 +1405,11 @@ out_nopush: | |||
1385 | sock_zerocopy_put(uarg); | 1405 | sock_zerocopy_put(uarg); |
1386 | return copied + copied_syn; | 1406 | return copied + copied_syn; |
1387 | 1407 | ||
1408 | do_error: | ||
1409 | skb = tcp_write_queue_tail(sk); | ||
1388 | do_fault: | 1410 | do_fault: |
1389 | if (!skb->len) { | 1411 | tcp_remove_empty_skb(sk, skb); |
1390 | tcp_unlink_write_queue(skb, sk); | ||
1391 | /* It is the one place in all of TCP, except connection | ||
1392 | * reset, where we can be unlinking the send_head. | ||
1393 | */ | ||
1394 | if (tcp_write_queue_empty(sk)) | ||
1395 | tcp_chrono_stop(sk, TCP_CHRONO_BUSY); | ||
1396 | sk_wmem_free_skb(sk, skb); | ||
1397 | } | ||
1398 | 1412 | ||
1399 | do_error: | ||
1400 | if (copied + copied_syn) | 1413 | if (copied + copied_syn) |
1401 | goto out; | 1414 | goto out; |
1402 | out_err: | 1415 | out_err: |