|
@@ -1428,12 +1428,12 @@ static void tcp_service_net_dma(struct sock *sk, bool wait)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off)
|
|
|
+static struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off)
|
|
|
{
|
|
|
struct sk_buff *skb;
|
|
|
u32 offset;
|
|
|
|
|
|
- skb_queue_walk(&sk->sk_receive_queue, skb) {
|
|
|
+ while ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) {
|
|
|
offset = seq - TCP_SKB_CB(skb)->seq;
|
|
|
if (tcp_hdr(skb)->syn)
|
|
|
offset--;
|
|
@@ -1441,6 +1441,11 @@ static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off)
|
|
|
*off = offset;
|
|
|
return skb;
|
|
|
}
|
|
|
+ /* This looks weird, but this can happen if TCP collapsing
|
|
|
+ * splitted a fat GRO packet, while we released socket lock
|
|
|
+ * in skb_splice_bits()
|
|
|
+ */
|
|
|
+ sk_eat_skb(sk, skb, false);
|
|
|
}
|
|
|
return NULL;
|
|
|
}
|
|
@@ -1520,8 +1525,10 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
|
|
|
tcp_rcv_space_adjust(sk);
|
|
|
|
|
|
/* Clean up data we have read: This will do ACK frames. */
|
|
|
- if (copied > 0)
|
|
|
+ if (copied > 0) {
|
|
|
+ tcp_recv_skb(sk, seq, &offset);
|
|
|
tcp_cleanup_rbuf(sk, copied);
|
|
|
+ }
|
|
|
return copied;
|
|
|
}
|
|
|
EXPORT_SYMBOL(tcp_read_sock);
|