diff options
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r-- | net/ipv4/tcp.c | 23 |
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) |