aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 2109ff4a1daf..5f6419341821 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1762,8 +1762,14 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
1762 } 1762 }
1763 1763
1764#ifdef CONFIG_NET_DMA 1764#ifdef CONFIG_NET_DMA
1765 if (tp->ucopy.dma_chan) 1765 if (tp->ucopy.dma_chan) {
1766 dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); 1766 if (tp->rcv_wnd == 0 &&
1767 !skb_queue_empty(&sk->sk_async_wait_queue)) {
1768 tcp_service_net_dma(sk, true);
1769 tcp_cleanup_rbuf(sk, copied);
1770 } else
1771 dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
1772 }
1767#endif 1773#endif
1768 if (copied >= target) { 1774 if (copied >= target) {
1769 /* Do not sleep, just process backlog. */ 1775 /* Do not sleep, just process backlog. */
@@ -2325,10 +2331,17 @@ static int tcp_repair_options_est(struct tcp_sock *tp,
2325 tp->rx_opt.mss_clamp = opt.opt_val; 2331 tp->rx_opt.mss_clamp = opt.opt_val;
2326 break; 2332 break;
2327 case TCPOPT_WINDOW: 2333 case TCPOPT_WINDOW:
2328 if (opt.opt_val > 14) 2334 {
2329 return -EFBIG; 2335 u16 snd_wscale = opt.opt_val & 0xFFFF;
2336 u16 rcv_wscale = opt.opt_val >> 16;
2337
2338 if (snd_wscale > 14 || rcv_wscale > 14)
2339 return -EFBIG;
2330 2340
2331 tp->rx_opt.snd_wscale = opt.opt_val; 2341 tp->rx_opt.snd_wscale = snd_wscale;
2342 tp->rx_opt.rcv_wscale = rcv_wscale;
2343 tp->rx_opt.wscale_ok = 1;
2344 }
2332 break; 2345 break;
2333 case TCPOPT_SACK_PERM: 2346 case TCPOPT_SACK_PERM:
2334 if (opt.opt_val != 0) 2347 if (opt.opt_val != 0)