[LWN Logo]

Date:	Wed, 28 Apr 1999 08:09:35 -0700
From:	David Miller <davem@twiddle.net>
To:	ted@acacia.datacomm.com
Subject: Re: 48 day uptime problem?

   Date: Wed, 28 Apr 1999 07:48:39 -0700 (PDT)
   From: Ted Rolle <ted@acacia.datacomm.com>

   I mean, like this bug isn't more than 24 hours old!  C'mon, guys!!!

It's 48 days old, and sorry, we're just a bunch of "punk kids" who
think they're going to change the world :-)

Here's a patch against 2.2.7-pre4, please give it a try:

--- ./include/net/tcp.h.~1~	Wed Apr 28 11:49:54 1999
+++ ./include/net/tcp.h	Wed Apr 28 14:55:48 1999
@@ -716,6 +716,14 @@
 	return (new_win && (new_win > (cur_win << 1)));
 }
 
+/* TCP timestamps are only 32-bits, this causes a slight
+ * complication on 64-bit systems since we store a snapshot
+ * of jiffies in the buffer control blocks below.  We decidely
+ * only keep track of the low 32-bits and hide the ugly
+ * casts with the following macro.
+ */
+#define tcp_when(__X)	((__u32)(__X))
+
 /* This is what the send packet queueing engine uses to pass
  * TCP per-packet control information to the transmission
  * code.  We also store the host-order sequence numbers in
@@ -732,7 +740,7 @@
 	} header;	/* For incoming frames		*/
 	__u32		seq;		/* Starting sequence number	*/
 	__u32		end_seq;	/* SEQ + FIN + SYN + datalen	*/
-	unsigned long	when;		/* used to compute rtt's	*/
+	__u32		when;		/* used to compute rtt's	*/
 	__u8		flags;		/* TCP header flags.		*/
 
 	/* NOTE: These must match up to the flags byte in a
--- ./net/ipv4/tcp_input.c.~1~	Sat Apr 24 00:57:29 1999
+++ ./net/ipv4/tcp_input.c	Wed Apr 28 14:37:31 1999
@@ -97,7 +97,7 @@
 static void tcp_delack_estimator(struct tcp_opt *tp)
 {
 	if(tp->ato == 0) {
-		tp->lrcvtime = jiffies;
+		tp->lrcvtime = tcp_when(jiffies);
 
 		/* Help sender leave slow start quickly,
 		 * and also makes sure we do not take this
@@ -106,9 +106,9 @@
 		tp->ato = 1;
 		tcp_enter_quickack_mode(tp);
 	} else {
-		int m = jiffies - tp->lrcvtime;
+		int m = tcp_when(jiffies) - tp->lrcvtime;
 
-		tp->lrcvtime = jiffies;
+		tp->lrcvtime = tcp_when(jiffies);
 		if(m <= 0)
 			m = 1;
 		if(m > tp->rto)
@@ -231,7 +231,7 @@
 		 */
 		if((s32)(tp->rcv_tsval - tp->ts_recent) >= 0) {
 			tp->ts_recent = tp->rcv_tsval;
-			tp->ts_recent_stamp = jiffies;
+			tp->ts_recent_stamp = tcp_when(jiffies);
 		}
 	}
 }
@@ -241,7 +241,7 @@
 extern __inline__ int tcp_paws_discard(struct tcp_opt *tp, struct tcphdr *th, unsigned len)
 {
 	/* ts_recent must be younger than 24 days */
-	return (((s32)(jiffies - tp->ts_recent_stamp) >= PAWS_24DAYS) ||
+	return (((s32)(tcp_when(jiffies) - tp->ts_recent_stamp) >= PAWS_24DAYS) ||
 		(((s32)(tp->rcv_tsval - tp->ts_recent) < 0) &&
 		 /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM */
 		 (len != (th->doff * 4))));
@@ -609,7 +609,7 @@
 {
 	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
 	struct sk_buff *skb;
-	unsigned long now = jiffies;
+	__u32 now = tcp_when(jiffies);
 	int acked = 0;
 
 	/* If we are retransmitting, and this ACK clears up to
@@ -725,7 +725,7 @@
 	if (!(flag & FLAG_DATA_ACKED))
 		return;
 
-	seq_rtt = jiffies-tp->rcv_tsecr;
+	seq_rtt = tcp_when(jiffies) - tp->rcv_tsecr;
 	tcp_rtt_estimator(tp, seq_rtt);
 	if (tp->retransmits) {
 		if (tp->packets_out == 0) {
@@ -749,7 +749,7 @@
 static __inline__ void tcp_ack_packets_out(struct sock *sk, struct tcp_opt *tp)
 {
 	struct sk_buff *skb = skb_peek(&sk->write_queue);
-	long when = tp->rto - (jiffies - TCP_SKB_CB(skb)->when);
+	__u32 when = tp->rto - (tcp_when(jiffies) - TCP_SKB_CB(skb)->when);
 
 	/* Some data was ACK'd, if still retransmitting (due to a
 	 * timeout), resend more of the retransmit queue.  The
@@ -778,7 +778,7 @@
 	if (tp->pending == TIME_KEEPOPEN)
 	  	tp->probes_out = 0;
 
-	tp->rcv_tstamp = jiffies;
+	tp->rcv_tstamp = tcp_when(jiffies);
 
 	/* If the ack is newer than sent or older than previous acks
 	 * then we can probably ignore it.
@@ -2112,7 +2112,7 @@
 				tp->tcp_header_len = sizeof(struct tcphdr);
 			if (tp->saw_tstamp) {
 				tp->ts_recent = tp->rcv_tsval;
-				tp->ts_recent_stamp = jiffies;
+				tp->ts_recent_stamp = tcp_when(jiffies);
 			}
 
 			/* Can't be earlier, doff would be wrong. */
@@ -2136,7 +2136,7 @@
 				tcp_parse_options(sk, th, tp, 0);
 				if (tp->saw_tstamp) {
 					tp->ts_recent = tp->rcv_tsval;
-					tp->ts_recent_stamp = jiffies;
+					tp->ts_recent_stamp = tcp_when(jiffies);
 				}
 				
 				tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;
--- ./net/ipv4/tcp_output.c.~1~	Thu Apr 22 05:39:03 1999
+++ ./net/ipv4/tcp_output.c	Wed Apr 28 14:34:19 1999
@@ -167,7 +167,7 @@
 
 	if (!force_queue && tp->send_head == NULL && tcp_snd_test(sk, skb)) {
 		/* Send it out now. */
-		TCP_SKB_CB(skb)->when = jiffies;
+		TCP_SKB_CB(skb)->when = tcp_when(jiffies);
 		tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
 		tp->packets_out++;
 		tcp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL));
@@ -344,7 +344,7 @@
 
 			/* Advance the send_head.  This one is going out. */
 			update_send_head(sk);
-			TCP_SKB_CB(skb)->when = jiffies;
+			TCP_SKB_CB(skb)->when = tcp_when(jiffies);
 			tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
 			tp->packets_out++;
 			tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
@@ -600,7 +600,7 @@
 	/* Make a copy, if the first transmission SKB clone we made
 	 * is still in somebody's hands, else make a clone.
 	 */
-	TCP_SKB_CB(skb)->when = jiffies;
+	TCP_SKB_CB(skb)->when = tcp_when(jiffies);
 	if(skb_cloned(skb))
 		skb = skb_copy(skb, GFP_ATOMIC);
 	else
@@ -723,7 +723,7 @@
 		   tp->packets_out &&
 		   !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_URG)) {
 			update_send_head(sk);
-			TCP_SKB_CB(skb)->when = jiffies;
+			TCP_SKB_CB(skb)->when = tcp_when(jiffies);
 			tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
 			tp->packets_out++;
 			tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
@@ -778,7 +778,7 @@
 	/* Send it off. */
 	TCP_SKB_CB(skb)->seq = tp->write_seq;
 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
-	TCP_SKB_CB(skb)->when = jiffies;
+	TCP_SKB_CB(skb)->when = tcp_when(jiffies);
 	tcp_transmit_skb(sk, skb);
 }
 
@@ -808,7 +808,7 @@
 	TCP_SKB_CB(skb)->seq = tp->snd_una;
 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1;
 	__skb_queue_tail(&sk->write_queue, skb);
-	TCP_SKB_CB(skb)->when = jiffies;
+	TCP_SKB_CB(skb)->when = tcp_when(jiffies);
 	tp->packets_out++;
 	tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
 	return 0;
@@ -875,7 +875,7 @@
 	/* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */
 	th->window = htons(req->rcv_wnd);
 
-	TCP_SKB_CB(skb)->when = jiffies;
+	TCP_SKB_CB(skb)->when = tcp_when(jiffies);
 	tcp_syn_build_options((__u32 *)(th + 1), req->mss, req->tstamp_ok,
 			      req->sack_ok, req->wscale_ok, req->rcv_wscale,
 			      TCP_SKB_CB(skb)->when,
@@ -963,7 +963,7 @@
 
 	/* Send it off. */
 	__skb_queue_tail(&sk->write_queue, buff);
-	TCP_SKB_CB(buff)->when = jiffies;
+	TCP_SKB_CB(buff)->when = tcp_when(jiffies);
 	tp->packets_out++;
 	tcp_transmit_skb(sk, skb_clone(buff, GFP_KERNEL));
 	tcp_statistics.TcpActiveOpens++;
@@ -1037,7 +1037,7 @@
 
 		/* Send it off, this clears delayed acks for us. */
 		TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tp->snd_nxt;
-		TCP_SKB_CB(buff)->when = jiffies;
+		TCP_SKB_CB(buff)->when = tcp_when(jiffies);
 		tcp_transmit_skb(sk, buff);
 	}
 }
@@ -1075,7 +1075,7 @@
 					return; /* Let a retransmit get it. */
 			}
 			update_send_head(sk);
-			TCP_SKB_CB(skb)->when = jiffies;
+			TCP_SKB_CB(skb)->when = tcp_when(jiffies);
 			tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
 			tp->packets_out++;
 			tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
@@ -1101,7 +1101,7 @@
 			 */
 			TCP_SKB_CB(skb)->seq = tp->snd_nxt - 1;
 			TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
-			TCP_SKB_CB(skb)->when = jiffies;
+			TCP_SKB_CB(skb)->when = tcp_when(jiffies);
 			tcp_transmit_skb(sk, skb);
 		}
 	}
--- ./net/ipv4/tcp_ipv4.c.~1~	Sat Apr 24 00:57:20 1999
+++ ./net/ipv4/tcp_ipv4.c	Wed Apr 28 14:38:15 1999
@@ -1430,7 +1430,7 @@
 		}
 		if (newtp->tstamp_ok) {
 			newtp->ts_recent = req->ts_recent;
-			newtp->ts_recent_stamp = jiffies;
+			newtp->ts_recent_stamp = tcp_when(jiffies);
 			newtp->tcp_header_len = sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED;
 		} else {
 			newtp->tcp_header_len = sizeof(struct tcphdr);
--- ./net/ipv4/tcp_timer.c.~1~	Thu Apr 22 05:39:03 1999
+++ ./net/ipv4/tcp_timer.c	Wed Apr 28 14:40:23 1999
@@ -224,7 +224,7 @@
 
 	if ((1<<sk->state) & (TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_FIN_WAIT2)) {
 		struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-		__u32 elapsed = jiffies - tp->rcv_tstamp;
+		__u32 elapsed = tcp_when(jiffies) - tp->rcv_tstamp;
 
 		if (elapsed >= sysctl_tcp_keepalive_time) {
 			if (tp->probes_out > sysctl_tcp_keepalive_probes) {
@@ -561,7 +561,7 @@
 						if (!tp->syn_wait_queue)
 							break;
 					} else {
-						__u32 timeo;
+						unsigned long timeo;
 						struct open_request *op; 
 
 						(*conn->class->rtx_syn_ack)(sk, conn);

-
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/