Received: by 2002:a25:c593:0:0:0:0:0 with SMTP id v141csp4089169ybe; Mon, 9 Sep 2019 04:07:34 -0700 (PDT) X-Google-Smtp-Source: APXvYqwMrOV4T7s2fiSPAKmod0dcsVGIQiidivruTN0ZyuC/D8EKxpiH8BfPT9eB00R+xytpBlO1 X-Received: by 2002:aa7:da18:: with SMTP id r24mr24166858eds.37.1568027254343; Mon, 09 Sep 2019 04:07:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1568027254; cv=none; d=google.com; s=arc-20160816; b=eqlLYnh9dt5n7WRZhJiXL2HY237up3JjsHOzxbK5Ku/925rYPpIhBmqukPHqqIAAsM H/NDUgYiFV2RVltQNm13y5GsezXHReOKHFeFQj+sl5JXO32ZG2kg2L1U1Pq2krR9ATVi 38CbXc0TXo1wZMzqN13d2M6/LGZofy3Mof69NNTuo8+Vbr7zSPQ8UoE+OwRQdYbQ6PwY AifLkLRHtZx217gFk+xYc+uN7iCguqASDKJfgB9Gnv24Bl+27CDl6CthgJ1jrNO4xZwC azaGVWU77g9m5hfEWF9lU4O4kAVql8XdCG1NqXrFR1cRke+EbrJ08+ndWP82KG1KuXZD sSyg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=J29giVvSG2tHJHcVhuY4vDR6DFAqS1bhBA4SahiLQE0=; b=b5JXuD5gx3eLo1+ZglI0CnDGp4/PW2ZUnAAcL4l2HlAZViBnRJLOz62szqOI+j2iOo jH+uercOqE3kZFvPHgzuMfbZo+DopyWRZSrJlIl8fbAEetLhWHSs+lG7aJhsJas1GdPn BxU/tbejWXMJNfsD9SFu0SzExdZu8agvE7K8+oOD6Qf22O+y/lP/SkQ+p6X2Kh8EG6az gSjWAY3NE83c2q1qI/9z/Br9x2dz3lSZYQ2eXq84zD7Krqn62a4KZTTvGKH+n2omK9Aq AlUwUUbKdxN9dWCX/0vE4Dt40XPng6nuPi3PgxRrHsqIL4ZmAqQ7tj20fio7hZPDXP+K N2sQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=B5rrNe+4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y19si922407edr.66.2019.09.09.04.07.10; Mon, 09 Sep 2019 04:07:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=B5rrNe+4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730890AbfIHMsG (ORCPT + 99 others); Sun, 8 Sep 2019 08:48:06 -0400 Received: from mail.kernel.org ([198.145.29.99]:36942 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730581AbfIHMsE (ORCPT ); Sun, 8 Sep 2019 08:48:04 -0400 Received: from localhost (unknown [62.28.240.114]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 68307218AF; Sun, 8 Sep 2019 12:48:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1567946883; bh=/VQkcCH+Ha5GIPR0GqNZAJ+IMWszjwFCdA1MJFfVhMI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=B5rrNe+4zgNc1U4Q0lPXMCXAZsQMxeNWB0TUtoHbcayRJHEogj1Bq2UvlsFWZYLuV KyoC+SPHyncOCdRpRKdD/YxB2jM8rptxptQ6aA9uXASXiRgqvl7k4U0Wm7hCrt9or0 djTkzY6bKfs+WS2gfaFzjaroONF1DyebRmCbnRJk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Eric Dumazet , Jason Baron , Vladimir Rutsky , Soheil Hassas Yeganeh , Neal Cardwell , "David S. Miller" Subject: [PATCH 4.19 07/57] tcp: remove empty skb from write queue in error cases Date: Sun, 8 Sep 2019 13:41:31 +0100 Message-Id: <20190908121127.847109183@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190908121125.608195329@linuxfoundation.org> References: <20190908121125.608195329@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Dumazet [ Upstream commit fdfc5c8594c24c5df883583ebd286321a80e0a67 ] Vladimir Rutsky reported stuck TCP sessions after memory pressure events. Edge Trigger epoll() user would never receive an EPOLLOUT notification allowing them to retry a sendmsg(). Jason tested the case of sk_stream_alloc_skb() returning NULL, but there are other paths that could lead both sendmsg() and sendpage() to return -1 (EAGAIN), with an empty skb queued on the write queue. This patch makes sure we remove this empty skb so that Jason code can detect that the queue is empty, and call sk->sk_write_space(sk) accordingly. Fixes: ce5ec440994b ("tcp: ensure epoll edge trigger wakeup when write queue is empty") Signed-off-by: Eric Dumazet Cc: Jason Baron Reported-by: Vladimir Rutsky Cc: Soheil Hassas Yeganeh Cc: Neal Cardwell Acked-by: Soheil Hassas Yeganeh Acked-by: Neal Cardwell Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/tcp.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -934,6 +934,22 @@ static int tcp_send_mss(struct sock *sk, return mss_now; } +/* In some cases, both sendpage() and sendmsg() could have added + * an skb to the write queue, but failed adding payload on it. + * We need to remove it to consume less memory, but more + * importantly be able to generate EPOLLOUT for Edge Trigger epoll() + * users. + */ +static void tcp_remove_empty_skb(struct sock *sk, struct sk_buff *skb) +{ + if (skb && !skb->len) { + tcp_unlink_write_queue(skb, sk); + if (tcp_write_queue_empty(sk)) + tcp_chrono_stop(sk, TCP_CHRONO_BUSY); + sk_wmem_free_skb(sk, skb); + } +} + ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, size_t size, int flags) { @@ -1056,6 +1072,7 @@ out: return copied; do_error: + tcp_remove_empty_skb(sk, tcp_write_queue_tail(sk)); if (copied) goto out; out_err: @@ -1409,17 +1426,11 @@ out_nopush: sock_zerocopy_put(uarg); return copied + copied_syn; +do_error: + skb = tcp_write_queue_tail(sk); do_fault: - if (!skb->len) { - tcp_unlink_write_queue(skb, sk); - /* It is the one place in all of TCP, except connection - * reset, where we can be unlinking the send_head. - */ - tcp_check_send_head(sk, skb); - sk_wmem_free_skb(sk, skb); - } + tcp_remove_empty_skb(sk, skb); -do_error: if (copied + copied_syn) goto out; out_err: