Re: Networking problems with 2.3.41-pre3

From: David S. Miller (davem@redhat.com)
Date: Thu Jan 27 2000 - 04:57:02 EST


Try this patch, already sent to Linus:

diff -u --recursive --new-file --exclude=CVS --exclude=.cvsignore vanilla/linux/include/net/tcp.h linux/include/net/tcp.h
--- vanilla/linux/include/net/tcp.h Mon Jan 24 18:15:40 2000
+++ linux/include/net/tcp.h Mon Jan 24 19:09:24 2000
@@ -975,7 +975,7 @@
 {
         __u32 cwnd;
 
- if (!tp->srtt || tp->srtt > (HZ/50) || tp->mss_cache > 1460)
+ if (!tp->srtt || tp->srtt > ((HZ/50)<<3) || tp->mss_cache > 1460)
                 cwnd = 2;
         else if (tp->mss_cache > 1095)
                 cwnd = 3;
diff -u --recursive --new-file --exclude=CVS --exclude=.cvsignore vanilla/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- vanilla/linux/net/ipv4/tcp.c Mon Jan 24 18:15:41 2000
+++ linux/net/ipv4/tcp.c Mon Jan 24 10:40:32 2000
@@ -5,7 +5,7 @@
  *
  * Implementation of the Transmission Control Protocol(TCP).
  *
- * Version: $Id: tcp.c,v 1.158 2000/01/21 23:45:57 davem Exp $
+ * Version: $Id: tcp.c,v 1.160 2000/01/24 18:40:32 davem Exp $
  *
  * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
  * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -1027,7 +1027,6 @@
         TCP_CHECK_TIMER(sk);
 out_unlock:
         release_sock(sk);
- tcp_push_pending_frames(sk, tp);
         return err;
 }
 
@@ -1347,6 +1346,35 @@
 
                         BUG_TRAP(tp->copied_seq == tp->rcv_nxt);
 
+ /* Ugly... If prequeue is not empty, we have to
+ * process it before releasing socket, otherwise
+ * order will be broken at second iteration.
+ * More elegant solution is required!!!
+ *
+ * Look: we have the following (pseudo)queues:
+ *
+ * 1. packets in flight
+ * 2. backlog
+ * 3. prequeue
+ * 4. receive_queue
+ *
+ * Each queue can be processed only if the next ones
+ * are empty. At this point we have empty receive_queue.
+ * But prequeue _can_ be not empty after second iteration,
+ * when we jumped to start of loop because backlog
+ * processing added something to receive_queue.
+ * We cannot release_sock(), because backlog contains
+ * packets arrived _after_ prequeued ones.
+ *
+ * Shortly, algorithm is clear --- to process all
+ * the queues in order. We could make it more directly,
+ * requeueing packets from backlog to prequeue, if
+ * is not empty. It is more elegant, but eats cycles,
+ * unfortunately.
+ */
+ if (skb_queue_len(&tp->ucopy.prequeue))
+ goto do_prequeue;
+
                         /* __ Set realtime policy in scheduler __ */
                 }
 
@@ -1371,6 +1399,7 @@
 
                         if (tp->rcv_nxt == tp->copied_seq &&
                             skb_queue_len(&tp->ucopy.prequeue)) {
+do_prequeue:
                                 tcp_prequeue_process(sk);
 
                                 if ((chunk = len - tp->ucopy.len) != 0) {
diff -u --recursive --new-file --exclude=CVS --exclude=.cvsignore vanilla/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- vanilla/linux/net/ipv4/tcp_input.c Mon Jan 24 18:15:41 2000
+++ linux/net/ipv4/tcp_input.c Mon Jan 24 10:40:33 2000
@@ -5,7 +5,7 @@
  *
  * Implementation of the Transmission Control Protocol(TCP).
  *
- * Version: $Id: tcp_input.c,v 1.182 2000/01/21 23:45:59 davem Exp $
+ * Version: $Id: tcp_input.c,v 1.183 2000/01/24 18:40:33 davem Exp $
  *
  * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
  * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -1323,7 +1323,11 @@
         if (th->doff > (sizeof(struct tcphdr)>>2) && tw->ts_recent_stamp) {
                 tcp_parse_options(NULL, th, &tp, 0);
 
- paws_reject = tp.saw_tstamp && tcp_paws_check(&tp, th->rst);
+ if (tp.saw_tstamp) {
+ tp.ts_recent = tw->ts_recent;
+ tp.ts_recent_stamp = tw->ts_recent_stamp;
+ paws_reject = tcp_paws_check(&tp, th->rst);
+ }
         }
 
         if (tw->substate == TCP_FIN_WAIT2) {
@@ -2832,7 +2836,15 @@
         if (th->doff > (sizeof(struct tcphdr)>>2)) {
                 tcp_parse_options(NULL, th, &ttp, 0);
 
- paws_reject = ttp.saw_tstamp && tcp_paws_check(&ttp, th->rst);
+ if (ttp.saw_tstamp) {
+ ttp.ts_recent = req->ts_recent;
+ /* We do not store true stamp, but it is not required,
+ * it can be estimated (approximately)
+ * from another data.
+ */
+ ttp.ts_recent_stamp = xtime.tv_sec - ((TCP_TIMEOUT_INIT/HZ)<<req->retrans);
+ paws_reject = tcp_paws_check(&ttp, th->rst);
+ }
         }
 
         /* Check for pure retransmited SYN. */
@@ -3019,12 +3031,26 @@
                  * checked in SYN-SENT unlike another states, hence
                  * echoed tstamp must be checked too.
                  */
- if (tp->saw_tstamp &&
- ((__s32)(tp->rcv_tsecr - tcp_time_stamp) > 0 ||
- (__s32)(tp->rcv_tsecr - tp->syn_stamp) < 0)) {
- NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "TCP: synsent reject.\n"));
- NET_INC_STATS_BH(PAWSActiveRejected);
- return 1;
+ if (tp->saw_tstamp) {
+ if (tp->rcv_tsecr == 0) {
+ /* Workaround for bug in linux-2.1 and early
+ * 2.2 kernels. Let's pretend that we did not
+ * see such timestamp to avoid bogus rtt value,
+ * calculated by tcp_ack().
+ */
+ tp->saw_tstamp = 0;
+
+ /* But do not forget to store peer's timestamp! */
+ if (th->syn) {
+ tp->ts_recent = tp->rcv_tsval;
+ tp->ts_recent_stamp = xtime.tv_sec;
+ }
+ } else if ((__s32)(tp->rcv_tsecr - tcp_time_stamp) > 0 ||
+ (__s32)(tp->rcv_tsecr - tp->syn_stamp) < 0) {
+ NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "TCP: synsent reject.\n"));
+ NET_INC_STATS_BH(PAWSActiveRejected);
+ return 1;
+ }
                 }
 
                 /* Now ACK is acceptable.
@@ -3449,6 +3475,14 @@
                                         tmo = tcp_fin_time(tp);
                                         if (tmo > TCP_TIMEWAIT_LEN) {
                                                 tcp_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN);
+ } else if (th->fin || sk->lock.users) {
+ /* Bad case. We could lose such FIN otherwise.
+ * It is not a big problem, but it looks confusing
+ * and not so rare event. We still can lose it now,
+ * if it spins in bh_lock_sock(), but it is really
+ * marginal case.
+ */
+ tcp_reset_keepalive_timer(sk, tmo);
                                         } else {
                                                 tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
                                                 goto discard;
diff -u --recursive --new-file --exclude=CVS --exclude=.cvsignore vanilla/linux/net/packet/af_packet.c linux/net/packet/af_packet.c
--- vanilla/linux/net/packet/af_packet.c Mon Jan 24 18:15:41 2000
+++ linux/net/packet/af_packet.c Mon Jan 24 15:35:59 2000
@@ -5,7 +5,7 @@
  *
  * PACKET - implements raw packet sockets.
  *
- * Version: $Id: af_packet.c,v 1.27 2000/01/18 08:24:27 davem Exp $
+ * Version: $Id: af_packet.c,v 1.28 2000/01/24 23:35:59 davem Exp $
  *
  * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
  * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.rutgers.edu



This archive was generated by hypermail 2b29 : Mon Jan 31 2000 - 21:00:33 EST