From: Jakub Kicinski Date: Sat, 30 Apr 2022 02:12:05 +0000 (-0700) Subject: Merge branch 'tcp-pass-back-data-left-in-socket-after-receive' of git://git.kernel... X-Git-Tag: v5.19~462^2~228 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=0813aeee0d02d80912c86b2b3a1ebdb4ee4476ba;p=mirror_ubuntu-kernels.git Merge branch 'tcp-pass-back-data-left-in-socket-after-receive' of git://git.kernel.org/pub/scm/linux/kernel/git/kuba/linux Signed-off-by: Jakub Kicinski --- 0813aeee0d02d80912c86b2b3a1ebdb4ee4476ba diff --cc net/ipv4/tcp.c index db55af9eb37b,bb7ef45408e1..b44fde435bd1 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@@ -2314,9 -2335,11 +2314,11 @@@ static int tcp_recvmsg_locked(struct so if (sk->sk_state == TCP_LISTEN) goto out; - if (tp->recvmsg_inq) + if (tp->recvmsg_inq) { *cmsg_flags = TCP_CMSG_INQ; + msg->msg_get_inq = 1; + } - timeo = sock_rcvtimeo(sk, nonblock); + timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); /* Urgent data needs to be handled specially. */ if (flags & MSG_OOB) @@@ -2534,10 -2558,10 +2536,10 @@@ recv_sndq goto out; } -int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, - int flags, int *addr_len) +int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags, + int *addr_len) { - int cmsg_flags = 0, ret, inq; + int cmsg_flags = 0, ret; struct scm_timestamping_internal tss; if (unlikely(flags & MSG_ERRQUEUE)) @@@ -2546,18 -2570,22 +2548,20 @@@ if (sk_can_busy_loop(sk) && skb_queue_empty_lockless(&sk->sk_receive_queue) && sk->sk_state == TCP_ESTABLISHED) - sk_busy_loop(sk, nonblock); + sk_busy_loop(sk, flags & MSG_DONTWAIT); lock_sock(sk); - ret = tcp_recvmsg_locked(sk, msg, len, nonblock, flags, &tss, - &cmsg_flags); + ret = tcp_recvmsg_locked(sk, msg, len, flags, &tss, &cmsg_flags); release_sock(sk); - sk_defer_free_flush(sk); - if (cmsg_flags && ret >= 0) { + if ((cmsg_flags || msg->msg_get_inq) && ret >= 0) { if (cmsg_flags & TCP_CMSG_TS) tcp_recv_timestamp(msg, sk, &tss); - if (cmsg_flags & TCP_CMSG_INQ) { - inq = tcp_inq_hint(sk); - put_cmsg(msg, SOL_TCP, TCP_CM_INQ, sizeof(inq), &inq); + if (msg->msg_get_inq) { + msg->msg_inq = tcp_inq_hint(sk); + if (cmsg_flags & TCP_CMSG_INQ) + put_cmsg(msg, SOL_TCP, TCP_CM_INQ, + sizeof(msg->msg_inq), &msg->msg_inq); } } return ret;