From: Martin Pool <mbp@samba.org>
To: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Cc: davem@redhat.com, ak@muc.de, netdev@oss.sgi.com, Alan.Cox@linux.org
Subject: Re: FIN_WAIT1 / TCP_CORK / 2.2 -- reproducible bug and test case
Date: Thu, 26 Sep 2002 15:47:46 +1000 [thread overview]
Message-ID: <20020926054721.GA6039@samba.org> (raw)
In-Reply-To: <200209182338.DAA00778@mops.inr.ac.ru>
On 19 Sep 2002, Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> wrote:
> Hello!
>
> > I can't reproduce it on 2.4.18 or .19. It looked to me like
> > tcp_snd_test() and related stuff had been substantially rewritten.
>
> No, tcp_snd_test() in 2.2 is backport and it is accurate.
> Apparently, the problem remained in another place, which was not backported.
>
> I think this is tcp_send_fin(). It is obscure and apparently incorrect
> at least on corked sockets. I would kill all the dubious "if" after
>
> /* Special case to avoid Nagle bogosity....
>
> and replaced it with straight tcp_push_pending_frames() like it was
> made in 2.4. Please, try.
Thanks for the hint! The change you suggested seems to reliably fix
the problem but I saw something else as well.
I was also a bit confused by the purpose of the (skb->len < mss_now)
term in tcp_send_fin(). As far as I can see, that if statement is to
do with deciding whether to make up a new FIN packet, or whether to
set the FIN bit on the final packet that is already queued.
It seems to me that in 2.2.21, if we ever have frames queued in
tp->send_head, and altogether they are more than the MSS, then it will
go through to the else branch, and make up and send a FIN packet
straight away. The FIN packet will be transmitted before the other
packets that are queued, even though they are earlier in sequence.
So, assuming no selective ACK, it will arrive out of order and just
have to be retransmitted later on.
I see that that test is gone in 2.4.18, and the expression is simply
(tp->send_head != NULL).
The patch is just below. It works with 2.2.22 too. If somebody could
let me know if it's OK I would appreciate it.
> BTW your tcpdump contains less than 25% of packets. And all the interesting
> piece is absent completely. :-)
I think the interesting bit is absent from the dump because it really
*is* absent -- the machine just never sends a FIN. (Or perhaps
tcpdump missed some packets?)
--- linux-2.2.21-cork/net/ipv4/tcp_output.c.orig Thu Sep 26 07:34:52 2002
+++ linux-2.2.21-cork/net/ipv4/tcp_output.c Thu Sep 26 07:59:52 2002
@@ -753,38 +753,23 @@ void tcp_send_fin(struct sock *sk)
{
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
struct sk_buff *skb = skb_peek_tail(&sk->write_queue);
- unsigned int mss_now;
- /* Optimization, tack on the FIN if we have a queue of
- * unsent frames. But be careful about outgoing SACKS
- * and IP options.
- */
- mss_now = tcp_current_mss(sk);
+ if ((tp->send_head != NULL)) {
+ /* Optimization, tack on the FIN if we have a queue of
+ * unsent frames. But be careful about outgoing SACKS
+ * and IP options. Then send all outstanding frames,
+ * or turn on probe timer. */
- if((tp->send_head != NULL) && (skb->len < mss_now)) {
/* tcp_write_xmit() takes care of the rest. */
TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_FIN;
TCP_SKB_CB(skb)->end_seq++;
tp->write_seq++;
- /* Special case to avoid Nagle bogosity. If this
- * segment is the last segment, and it was queued
- * due to Nagle/SWS-avoidance, send it out now.
- */
- if(tp->send_head == skb &&
- !sk->nonagle &&
- skb->len < (tp->mss_cache >> 1) &&
- tp->packets_out &&
- !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_URG)) {
- update_send_head(sk);
- TCP_SKB_CB(skb)->when = tcp_time_stamp;
- tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
- tp->packets_out++;
- tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
- if(!tcp_timer_is_set(sk, TIME_RETRANS))
- tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
- }
+ tcp_push_pending_frames(sk, tp);
} else {
+ /* Nothing is currently pending on this socket; make a
+ * FIN packet and send it directly. */
+
/* Socket is locked, keep trying until memory is available. */
for (;;) {
skb = sock_wmalloc(sk,
--
Martin
Want a faster compiler? http://distcc.samba.org/
next prev parent reply other threads:[~2002-09-26 5:47 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-09-18 2:03 FIN_WAIT1 / TCP_CORK / 2.2 -- reproducible bug and test case Martin Pool
2002-09-18 1:58 ` David S. Miller
2002-09-18 2:09 ` Martin Pool
2002-09-18 23:38 ` Alexey Kuznetsov
2002-09-26 5:47 ` Martin Pool [this message]
2002-09-26 13:09 ` kuznet
2002-09-26 20:46 ` David S. Miller
2002-09-30 9:59 ` Martin Pool
2002-09-30 10:32 ` David S. Miller
2002-09-30 12:23 ` Alan Cox
2002-10-03 3:30 ` James Morris
2002-10-03 3:54 ` Andi Kleen
2002-10-03 7:59 ` David S. Miller
2002-10-03 7:56 ` David S. Miller
2002-09-18 2:30 ` Martin Pool
-- strict thread matches above, loose matches on Subject: below --
2002-10-04 15:06 James Morris
2002-10-04 23:27 ` Martin Pool
2002-10-05 7:51 ` Martin Pool
2002-10-05 11:53 ` James Morris
2002-10-08 10:21 ` Martin Pool
2002-10-08 10:28 ` James Morris
2002-10-10 16:36 ` James Morris
2002-10-10 16:43 ` James Morris
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20020926054721.GA6039@samba.org \
--to=mbp@samba.org \
--cc=Alan.Cox@linux.org \
--cc=ak@muc.de \
--cc=davem@redhat.com \
--cc=kuznet@ms2.inr.ac.ru \
--cc=netdev@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).