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/