Messages in this thread Patch in this message | | | Date | Tue, 9 Mar 1999 07:02:16 -0800 | From | David Miller <> | Subject | Re: TCP window updates [Was: PROBLEM: Sending mail-attachment] |
| |
Date: Tue, 9 Mar 1999 15:21:56 +0100 (CET) From: Matthias Moeller <mattes@ice.robin.de>
This should put data on the wire if
1. there are no packets in flight. 2. we are not retransmitting. 3. the right edge of the frame does not exceed receivers window.
Ok.
Actually point 3. fails when I get the stall.
Your fix in cleanup_rbuf() makes the receiver send window updates but these might get lost in the network. There is no retrans timer because all data has been acked.
If all data has been sent and ack'd, it's no big deal and should not deadlock. Because even if the sender does not see the window open up enough, the retransmit timer on that packet will let one packet out. The only time data is pending and the retransmit timer is not active is when the 0 window probe time is running, and what it does is send a dummy "current sequence number - 1" frame to try and get an ack back. Once the ack comes back, with a suitable window, the probe timer turns off and the retransmit timer is re-enabled.
This is essentially how acks being dropped are handled by TCP.
Now we have to find the hole where this isn't working in your deadlock case :-)
I see one possible hole, and why 2.0.x wasn't effected yet did the same thing (sort of). Partial frames. The idea behind this scheme is that you hold onto non-full size frames until you're done with the user's current set of writes, hoping you can tack on later data and make a full sized one. (this fixed a bug we had in writev() when apache would write the http header then the data in subsequent iovec[] entries, we would send the tiny http header out in a tiny packet).
The bit of code you cite is where we try to catch the last partial frame. 2.0.x had an ugly timer which made sure it got sent eventually, if we didn't send it at tcp_sendmsg() time. I think here is the area of the problem, because in 2.2.x I bypass the PROBE0 tests when tacking on partial frames in tcp_send_skb(), but no code later rechecks it.
I hope this is it, it is untested, but please try this patch (against 2.2.3):
Later, David S. Miller davem@redhat.com
--- net/ipv4/tcp_ipv4.c.~1~ Mon Feb 22 17:19:07 1999 +++ net/ipv4/tcp_ipv4.c Tue Mar 9 06:44:56 1999 @@ -685,8 +685,15 @@ msg->msg_flags); /* Push out partial tail frames if needed. */ tp = &(sk->tp_pinfo.af_tcp); - if(tp->send_head && tcp_snd_test(sk, tp->send_head)) - tcp_write_xmit(sk); + if(tp->send_head) { + if(tcp_snd_test(sk, tp->send_head)) + tcp_write_xmit(sk); + else if (tp->packets_out == 0 && !tp->pending) { + /* We held off on this in tcp_send_skb() */ + tp->pending = TIME_PROBE0; + tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto); + } + } release_sock(sk); out:
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |