aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_timer.c')
-rw-r--r--net/ipv4/tcp_timer.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 655dd8d7f064..7014cc00c74c 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -156,8 +156,13 @@ static bool retransmits_timed_out(struct sock *sk,
156 return false; 156 return false;
157 157
158 start_ts = tcp_sk(sk)->retrans_stamp; 158 start_ts = tcp_sk(sk)->retrans_stamp;
159 if (unlikely(!start_ts)) 159 if (unlikely(!start_ts)) {
160 start_ts = tcp_skb_timestamp(tcp_write_queue_head(sk)); 160 struct sk_buff *head = tcp_rtx_queue_head(sk);
161
162 if (!head)
163 return false;
164 start_ts = tcp_skb_timestamp(head);
165 }
161 166
162 if (likely(timeout == 0)) { 167 if (likely(timeout == 0)) {
163 linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base); 168 linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base);
@@ -304,11 +309,12 @@ static void tcp_delack_timer(unsigned long data)
304static void tcp_probe_timer(struct sock *sk) 309static void tcp_probe_timer(struct sock *sk)
305{ 310{
306 struct inet_connection_sock *icsk = inet_csk(sk); 311 struct inet_connection_sock *icsk = inet_csk(sk);
312 struct sk_buff *skb = tcp_send_head(sk);
307 struct tcp_sock *tp = tcp_sk(sk); 313 struct tcp_sock *tp = tcp_sk(sk);
308 int max_probes; 314 int max_probes;
309 u32 start_ts; 315 u32 start_ts;
310 316
311 if (tp->packets_out || !tcp_send_head(sk)) { 317 if (tp->packets_out || !skb) {
312 icsk->icsk_probes_out = 0; 318 icsk->icsk_probes_out = 0;
313 return; 319 return;
314 } 320 }
@@ -321,9 +327,9 @@ static void tcp_probe_timer(struct sock *sk)
321 * corresponding system limit. We also implement similar policy when 327 * corresponding system limit. We also implement similar policy when
322 * we use RTO to probe window in tcp_retransmit_timer(). 328 * we use RTO to probe window in tcp_retransmit_timer().
323 */ 329 */
324 start_ts = tcp_skb_timestamp(tcp_send_head(sk)); 330 start_ts = tcp_skb_timestamp(skb);
325 if (!start_ts) 331 if (!start_ts)
326 tcp_send_head(sk)->skb_mstamp = tp->tcp_mstamp; 332 skb->skb_mstamp = tp->tcp_mstamp;
327 else if (icsk->icsk_user_timeout && 333 else if (icsk->icsk_user_timeout &&
328 (s32)(tcp_time_stamp(tp) - start_ts) > 334 (s32)(tcp_time_stamp(tp) - start_ts) >
329 jiffies_to_msecs(icsk->icsk_user_timeout)) 335 jiffies_to_msecs(icsk->icsk_user_timeout))
@@ -408,7 +414,7 @@ void tcp_retransmit_timer(struct sock *sk)
408 if (!tp->packets_out) 414 if (!tp->packets_out)
409 goto out; 415 goto out;
410 416
411 WARN_ON(tcp_write_queue_empty(sk)); 417 WARN_ON(tcp_rtx_queue_empty(sk));
412 418
413 tp->tlp_high_seq = 0; 419 tp->tlp_high_seq = 0;
414 420
@@ -441,7 +447,7 @@ void tcp_retransmit_timer(struct sock *sk)
441 goto out; 447 goto out;
442 } 448 }
443 tcp_enter_loss(sk); 449 tcp_enter_loss(sk);
444 tcp_retransmit_skb(sk, tcp_write_queue_head(sk), 1); 450 tcp_retransmit_skb(sk, tcp_rtx_queue_head(sk), 1);
445 __sk_dst_reset(sk); 451 __sk_dst_reset(sk);
446 goto out_reset_timer; 452 goto out_reset_timer;
447 } 453 }
@@ -473,7 +479,7 @@ void tcp_retransmit_timer(struct sock *sk)
473 479
474 tcp_enter_loss(sk); 480 tcp_enter_loss(sk);
475 481
476 if (tcp_retransmit_skb(sk, tcp_write_queue_head(sk), 1) > 0) { 482 if (tcp_retransmit_skb(sk, tcp_rtx_queue_head(sk), 1) > 0) {
477 /* Retransmission failed because of local congestion, 483 /* Retransmission failed because of local congestion,
478 * do not backoff. 484 * do not backoff.
479 */ 485 */
@@ -647,7 +653,7 @@ static void tcp_keepalive_timer (unsigned long data)
647 elapsed = keepalive_time_when(tp); 653 elapsed = keepalive_time_when(tp);
648 654
649 /* It is alive without keepalive 8) */ 655 /* It is alive without keepalive 8) */
650 if (tp->packets_out || tcp_send_head(sk)) 656 if (tp->packets_out || !tcp_write_queue_empty(sk))
651 goto resched; 657 goto resched;
652 658
653 elapsed = keepalive_time_elapsed(tp); 659 elapsed = keepalive_time_elapsed(tp);