Merge tag 'v5.7-rc7' into perf/core, to pick up fixes
[linux-2.6-microblaze.git] / net / ipv4 / tcp.c
index 6d87de4..dd40175 100644 (file)
@@ -476,9 +476,17 @@ static void tcp_tx_timestamp(struct sock *sk, u16 tsflags)
 static inline bool tcp_stream_is_readable(const struct tcp_sock *tp,
                                          int target, struct sock *sk)
 {
-       return (READ_ONCE(tp->rcv_nxt) - READ_ONCE(tp->copied_seq) >= target) ||
-               (sk->sk_prot->stream_memory_read ?
-               sk->sk_prot->stream_memory_read(sk) : false);
+       int avail = READ_ONCE(tp->rcv_nxt) - READ_ONCE(tp->copied_seq);
+
+       if (avail > 0) {
+               if (avail >= target)
+                       return true;
+               if (tcp_rmem_pressure(sk))
+                       return true;
+       }
+       if (sk->sk_prot->stream_memory_read)
+               return sk->sk_prot->stream_memory_read(sk);
+       return false;
 }
 
 /*
@@ -1756,10 +1764,11 @@ static int tcp_zerocopy_receive(struct sock *sk,
 
        down_read(&current->mm->mmap_sem);
 
-       ret = -EINVAL;
        vma = find_vma(current->mm, address);
-       if (!vma || vma->vm_start > address || vma->vm_ops != &tcp_vm_ops)
-               goto out;
+       if (!vma || vma->vm_start > address || vma->vm_ops != &tcp_vm_ops) {
+               up_read(&current->mm->mmap_sem);
+               return -EINVAL;
+       }
        zc->length = min_t(unsigned long, zc->length, vma->vm_end - address);
 
        tp = tcp_sk(sk);
@@ -2154,13 +2163,15 @@ skip_copy:
                        tp->urg_data = 0;
                        tcp_fast_path_check(sk);
                }
-               if (used + offset < skb->len)
-                       continue;
 
                if (TCP_SKB_CB(skb)->has_rxtstamp) {
                        tcp_update_recv_tstamps(skb, &tss);
                        cmsg_flags |= 2;
                }
+
+               if (used + offset < skb->len)
+                       continue;
+
                if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
                        goto found_fin_ok;
                if (!(flags & MSG_PEEK))