From patchwork Mon Sep 12 17:35:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cong Wang X-Patchwork-Id: 12973842 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B433C6FA83 for ; Mon, 12 Sep 2022 17:36:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229760AbiILRgK (ORCPT ); Mon, 12 Sep 2022 13:36:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47104 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229836AbiILRgH (ORCPT ); Mon, 12 Sep 2022 13:36:07 -0400 Received: from mail-qk1-x732.google.com (mail-qk1-x732.google.com [IPv6:2607:f8b0:4864:20::732]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 91FA438475 for ; Mon, 12 Sep 2022 10:36:03 -0700 (PDT) Received: by mail-qk1-x732.google.com with SMTP id o7so2889079qkj.10 for ; Mon, 12 Sep 2022 10:36:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date; bh=++FcEJQ/W/MtAHDPHxofG8XpDMLkFGx/csr/y9/qQrQ=; b=dxyUEYEoE6j0fJzqpQJrcOtGMEQO5vKH/08jqF2IQ7L5zSeMQkZtiwGR8X1nPNGJub mryxt62WmGpRAJPgPzA3hptFsZSBOLXst/YifCEhudaCD6e6QZlBoQH5H1JQwAqzhz0E fymaAjfE2u2jWEGnZLC364auxy6h7ZQrvFPUI5c9/NKDG7SZ2zCQyXqPBqsLfNQOJjzI HwNyx69yVtCB0Czqd31eWfQGqze86IlxL2Q00vI3ukWa1Xd0fBiLmrVnAZfFLDz+nj5l umxoDHYQL+og9qwgkz1i0k0ca/2oJ5RMQfiLEbJu6Fq16XPVfryXDghYFYg6KknMo7sb TP8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date; bh=++FcEJQ/W/MtAHDPHxofG8XpDMLkFGx/csr/y9/qQrQ=; b=XT5Kk7IFfSnMJwjqB1PvbIeiIkjDZWYC99NggK/Njr3itcx+1iEXmGX+bZyaVwfjso +q78zGU1pHbZiUdE96AMY39vW9ygWxcSgLTJs0e2Q1DB6GvV1x90X0dYqfb1v8EqX0Zu d7SbURp/50X66lGwhyqcNqHQWxBlAj33YWknaPRnBRsacHArkZ6ZKUQJY1RfBYZYJDdp KPyA8IiGTp+IvzPmzeWMTEs0VxDlgRHzo1OtkeQRbA3f+epq+agSnQZyEH4AvPBudYg1 KZcm9kcUm1TO5PoknHVXja4oeE66/DXG3PPipHPK26QJurdwMPtqifLduCpNlqyH1+1Z BXoA== X-Gm-Message-State: ACgBeo3jNj42klWDfPbIyIPFKiLecS0IOAbQUTeG84pMHJJh4TGr152I MZruIPch/jP83+/sdELKvvcouR0xeeA= X-Google-Smtp-Source: AA6agR5IA8tgiuTWqWlzlxEAqol/7CtRLuVDKiXYKqxBQ0RsAPOqaykEfouAaTtLVzQxvXUF145F4g== X-Received: by 2002:a37:de09:0:b0:6c9:cac5:ceb7 with SMTP id h9-20020a37de09000000b006c9cac5ceb7mr19639713qkj.693.1663004162481; Mon, 12 Sep 2022 10:36:02 -0700 (PDT) Received: from pop-os.attlocal.net ([2600:1700:65a0:ab60:db7a:361d:46fa:c628]) by smtp.gmail.com with ESMTPSA id f5-20020a05622a1a0500b003445bb107basm7454889qtb.75.2022.09.12.10.36.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Sep 2022 10:36:01 -0700 (PDT) From: Cong Wang To: netdev@vger.kernel.org Cc: Cong Wang , Peilin Ye , John Fastabend , Jakub Sitnicki , Eric Dumazet Subject: [Patch net] tcp: read multiple skbs in tcp_read_skb() Date: Mon, 12 Sep 2022 10:35:53 -0700 Message-Id: <20220912173553.235838-1-xiyou.wangcong@gmail.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Cong Wang Before we switched to ->read_skb(), ->read_sock() was passed with desc.count=1, which technically indicates we only read one skb per ->sk_data_ready() call. However, for TCP, this is not true. TCP at least has sk_rcvlowat which intentionally holds skb's in receive queue until this watermark is reached. This means when ->sk_data_ready() is invoked there could be multiple skb's in the queue, therefore we have to read multiple skbs in tcp_read_skb() instead of one. Fixes: 965b57b469a5 ("net: Introduce a new proto_ops ->read_skb()") Reported-by: Peilin Ye Cc: John Fastabend Cc: Jakub Sitnicki Cc: Eric Dumazet Signed-off-by: Cong Wang --- net/ipv4/tcp.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 3488388eea5d..e373dde1f46f 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1761,19 +1761,28 @@ int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) if (sk->sk_state == TCP_LISTEN) return -ENOTCONN; - skb = tcp_recv_skb(sk, seq, &offset); - if (!skb) - return 0; + while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) { + u8 tcp_flags; + int used; - __skb_unlink(skb, &sk->sk_receive_queue); - WARN_ON_ONCE(!skb_set_owner_sk_safe(skb, sk)); - copied = recv_actor(sk, skb); - if (copied >= 0) { - seq += copied; - if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) + __skb_unlink(skb, &sk->sk_receive_queue); + WARN_ON_ONCE(!skb_set_owner_sk_safe(skb, sk)); + tcp_flags = TCP_SKB_CB(skb)->tcp_flags; + used = recv_actor(sk, skb); + consume_skb(skb); + if (used < 0) { + if (!copied) + copied = used; + break; + } + seq += used; + copied += used; + + if (tcp_flags & TCPHDR_FIN) { ++seq; + break; + } } - consume_skb(skb); WRITE_ONCE(tp->copied_seq, seq); tcp_rcv_space_adjust(sk);