summaryrefslogtreecommitdiff
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-10-01 14:52:40 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-10-01 14:52:40 -0300
commitaaf675f53a7176475f69595827248c8b2556ea8c (patch)
tree0cb744dec714328c9f89bf85553fb7195107e5d4 /net/ipv4/tcp.c
parent347c4e95845fad1853c0e3da6603a44c5d6122b3 (diff)
parenta0d271cbfed1dd50278c6b06bead3d00ba0a88f9 (diff)
downloadlinux-rt-aaf675f53a7176475f69595827248c8b2556ea8c.tar.gz
Merge tag 'v3.6' into staging/for_v3.7
Linux 3.6 * tag 'v3.6': (562 commits) Linux 3.6 vfs: dcache: fix deadlock in tree traversal mtdchar: fix offset overflow detection thp: avoid VM_BUG_ON page_count(page) false positives in __collapse_huge_page_copy iommu/amd: Fix wrong assumption in iommu-group specific code netdev: octeon: fix return value check in octeon_mgmt_init_phy() ALSA: snd-usb: fix next_packet_size calls for pause case inetpeer: fix token initialization qlcnic: Fix scheduling while atomic bug bnx2: Clean up remaining iounmap trivial select_parent documentation fix net: phy: smsc: Implement PHY config_init for LAN87xx smsc75xx: fix resume after device reset um: Preinclude include/linux/kern_levels.h um: Fix IPC on um netdev: pasemi: fix return value check in pasemi_mac_phy_init() team: fix return value check l2tp: fix return value check USB: Fix race condition when removing host controllers USB: ohci-at91: fix null pointer in ohci_hcd_at91_overcurrent_irq ...
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,
}
#ifdef CONFIG_NET_DMA
- if (tp->ucopy.dma_chan)
- dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+ if (tp->ucopy.dma_chan) {
+ if (tp->rcv_wnd == 0 &&
+ !skb_queue_empty(&sk->sk_async_wait_queue)) {
+ tcp_service_net_dma(sk, true);
+ tcp_cleanup_rbuf(sk, copied);
+ } else
+ dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+ }
#endif
if (copied >= target) {
/* Do not sleep, just process backlog. */
@@ -2325,10 +2331,17 @@ static int tcp_repair_options_est(struct tcp_sock *tp,
tp->rx_opt.mss_clamp = opt.opt_val;
break;
case TCPOPT_WINDOW:
- if (opt.opt_val > 14)
- return -EFBIG;
+ {
+ u16 snd_wscale = opt.opt_val & 0xFFFF;
+ u16 rcv_wscale = opt.opt_val >> 16;
+
+ if (snd_wscale > 14 || rcv_wscale > 14)
+ return -EFBIG;
- tp->rx_opt.snd_wscale = opt.opt_val;
+ tp->rx_opt.snd_wscale = snd_wscale;
+ tp->rx_opt.rcv_wscale = rcv_wscale;
+ tp->rx_opt.wscale_ok = 1;
+ }
break;
case TCPOPT_SACK_PERM:
if (opt.opt_val != 0)