Messages in this thread Patch in this message | | | From | (Christoph Lameter) | Subject | Fix for SLOW PPP Bug | Date | 6 Apr 1996 21:10:30 -0800 |
| |
I have tried to isolate when this bug was introduced and found that 1.3.72 works fine but 1.3.73 has the problem. I noticed some ACK changes in net/ipv4/tcp.c and made some diffs to revert those changes.
I applied the following patch to 1.3.73 and 1.3.84. The bug disppeared in both Kernel versions.
Studying the behaviour over a dialup link made me think about some other problems that I have noticed since a long time under linux:
- catting a long file via a dialup link leads to a stuttering display of the contents of the file (mtu 597). Sometimes the display stops for a second or more! (On an otherwise idle system..)
- Even on a LAN sometimes pauses develop in the display of characters.
Do we have someone who can troubleshoot the tcp stuff? I dont know what effect the change in tcp.c has. Just found it by trial and error.
--- tcp.c.new Sat Apr 6 18:52:10 1996 +++ tcp.c Sat Apr 6 20:24:19 1996 @@ -1347,6 +1347,7 @@ static inline void tcp_eat_skb(struct sock *sk, struct sk_buff * skb) { + sk->ack_backlog++; skb->sk = sk; __skb_unlink(skb, &sk->receive_queue); kfree_skb(skb, FREE_READ); @@ -1362,6 +1363,7 @@ static void cleanup_rbuf(struct sock *sk) { struct sk_buff *skb; + unsigned long rspace; /* * NOTE! The socket must be locked, so that we don't get @@ -1373,10 +1375,51 @@ tcp_eat_skb(sk, skb); } - /* If we raised the window due to cleaning up, tell the world.. */ - if (tcp_raise_window(sk)) { - sk->ack_backlog++; + /* + * FIXME: + * At this point we should send an ack if the difference + * in the window, and the amount of space is bigger than + * TCP_WINDOW_DIFF. + */ + + rspace=sock_rspace(sk); + if(sk->debug) + printk("sk->rspace = %lu\n", rspace); + /* + * This area has caused the most trouble. The current strategy + * is to simply do nothing if the other end has room to send at + * least 3 full packets, because the ack from those will auto- + * matically update the window. If the other end doesn't think + * we have much space left, but we have room for at least 1 more + * complete packet than it thinks we do, we will send an ack + * immediately. Otherwise we will wait up to .5 seconds in case + * the user reads some more. + */ + + /* + * It's unclear whether to use sk->mtu or sk->mss here. They differ only + * if the other end is offering a window smaller than the agreed on MSS + * (called sk->mtu here). In theory there's no connection between send + * and receive, and so no reason to think that they're going to send + * small packets. For the moment I'm using the hack of reducing the mss + * only on the send side, so I'm putting mtu here. + */ + + if (rspace > (sk->window - sk->bytes_rcv + sk->mtu)) + { + /* Send an ack right now. */ tcp_read_wakeup(sk); + } + else + { + /* Force it to send an ack soon. */ + int was_active = del_timer(&sk->retransmit_timer); + if (!was_active || jiffies+TCP_ACK_TIME < sk->timer.expires) + { + tcp_reset_xmit_timer(sk, TIME_WRITE, TCP_ACK_TIME); + } + else + add_timer(&sk->retransmit_timer); } }
| |