diff options
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 4a8ec457310f..8cdee120a50c 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -1950,6 +1950,50 @@ void tcp_v4_early_demux(struct sk_buff *skb) | |||
1950 | } | 1950 | } |
1951 | } | 1951 | } |
1952 | 1952 | ||
1953 | /* Packet is added to VJ-style prequeue for processing in process | ||
1954 | * context, if a reader task is waiting. Apparently, this exciting | ||
1955 | * idea (VJ's mail "Re: query about TCP header on tcp-ip" of 07 Sep 93) | ||
1956 | * failed somewhere. Latency? Burstiness? Well, at least now we will | ||
1957 | * see, why it failed. 8)8) --ANK | ||
1958 | * | ||
1959 | */ | ||
1960 | bool tcp_prequeue(struct sock *sk, struct sk_buff *skb) | ||
1961 | { | ||
1962 | struct tcp_sock *tp = tcp_sk(sk); | ||
1963 | |||
1964 | if (sysctl_tcp_low_latency || !tp->ucopy.task) | ||
1965 | return false; | ||
1966 | |||
1967 | if (skb->len <= tcp_hdrlen(skb) && | ||
1968 | skb_queue_len(&tp->ucopy.prequeue) == 0) | ||
1969 | return false; | ||
1970 | |||
1971 | __skb_queue_tail(&tp->ucopy.prequeue, skb); | ||
1972 | tp->ucopy.memory += skb->truesize; | ||
1973 | if (tp->ucopy.memory > sk->sk_rcvbuf) { | ||
1974 | struct sk_buff *skb1; | ||
1975 | |||
1976 | BUG_ON(sock_owned_by_user(sk)); | ||
1977 | |||
1978 | while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) { | ||
1979 | sk_backlog_rcv(sk, skb1); | ||
1980 | NET_INC_STATS_BH(sock_net(sk), | ||
1981 | LINUX_MIB_TCPPREQUEUEDROPPED); | ||
1982 | } | ||
1983 | |||
1984 | tp->ucopy.memory = 0; | ||
1985 | } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) { | ||
1986 | wake_up_interruptible_sync_poll(sk_sleep(sk), | ||
1987 | POLLIN | POLLRDNORM | POLLRDBAND); | ||
1988 | if (!inet_csk_ack_scheduled(sk)) | ||
1989 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, | ||
1990 | (3 * tcp_rto_min(sk)) / 4, | ||
1991 | TCP_RTO_MAX); | ||
1992 | } | ||
1993 | return true; | ||
1994 | } | ||
1995 | EXPORT_SYMBOL(tcp_prequeue); | ||
1996 | |||
1953 | /* | 1997 | /* |
1954 | * From tcp_input.c | 1998 | * From tcp_input.c |
1955 | */ | 1999 | */ |