@@ -1334,10 +1334,24 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
copy = min_t(int, copy, pfrag->size - pfrag->offset);
- if (tcp_downgrade_zcopy_pure(sk, skb) ||
- !sk_wmem_schedule(sk, copy))
+ if (tcp_downgrade_zcopy_pure(sk, skb))
goto wait_for_space;
+ if (unlikely(!sk_wmem_schedule(sk, copy))) {
+ int left;
+ /* We are in trouble if we have nothing queued.
+ * Use whatever is left in sk->sk_forward_alloc
+ * and tcp_wmem[0] to guarantee some progress.
+ */
+ left = sock_net(sk)->ipv4.sysctl_tcp_wmem[0] -
+ sk->sk_wmem_queued;
+ if (left > 0)
+ sk_forced_mem_schedule(sk, min(left, copy));
+
+ copy = min(copy, sk->sk_forward_alloc);
+ if (!copy)
+ goto wait_for_space;
+ }
err = skb_copy_to_page_nocache(sk, &msg->msg_iter, skb,
pfrag->page,
pfrag->offset,