diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index f030435e0eb4..f893e90061eb 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -555,6 +555,16 @@ static void tcp_event_data_recv(struct sock *sk, struct sk_buff *skb) | |||
555 | tcp_grow_window(sk, skb); | 555 | tcp_grow_window(sk, skb); |
556 | } | 556 | } |
557 | 557 | ||
558 | static u32 tcp_rto_min(struct sock *sk) | ||
559 | { | ||
560 | struct dst_entry *dst = __sk_dst_get(sk); | ||
561 | u32 rto_min = TCP_RTO_MIN; | ||
562 | |||
563 | if (dst && dst_metric_locked(dst, RTAX_RTO_MIN)) | ||
564 | rto_min = dst->metrics[RTAX_RTO_MIN-1]; | ||
565 | return rto_min; | ||
566 | } | ||
567 | |||
558 | /* Called to compute a smoothed rtt estimate. The data fed to this | 568 | /* Called to compute a smoothed rtt estimate. The data fed to this |
559 | * routine either comes from timestamps, or from segments that were | 569 | * routine either comes from timestamps, or from segments that were |
560 | * known _not_ to have been retransmitted [see Karn/Partridge | 570 | * known _not_ to have been retransmitted [see Karn/Partridge |
@@ -616,13 +626,13 @@ static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt) | |||
616 | if (tp->mdev_max < tp->rttvar) | 626 | if (tp->mdev_max < tp->rttvar) |
617 | tp->rttvar -= (tp->rttvar-tp->mdev_max)>>2; | 627 | tp->rttvar -= (tp->rttvar-tp->mdev_max)>>2; |
618 | tp->rtt_seq = tp->snd_nxt; | 628 | tp->rtt_seq = tp->snd_nxt; |
619 | tp->mdev_max = TCP_RTO_MIN; | 629 | tp->mdev_max = tcp_rto_min(sk); |
620 | } | 630 | } |
621 | } else { | 631 | } else { |
622 | /* no previous measure. */ | 632 | /* no previous measure. */ |
623 | tp->srtt = m<<3; /* take the measured time to be rtt */ | 633 | tp->srtt = m<<3; /* take the measured time to be rtt */ |
624 | tp->mdev = m<<1; /* make sure rto = 3*rtt */ | 634 | tp->mdev = m<<1; /* make sure rto = 3*rtt */ |
625 | tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN); | 635 | tp->mdev_max = tp->rttvar = max(tp->mdev, tcp_rto_min(sk)); |
626 | tp->rtt_seq = tp->snd_nxt; | 636 | tp->rtt_seq = tp->snd_nxt; |
627 | } | 637 | } |
628 | } | 638 | } |
@@ -755,7 +765,15 @@ void tcp_update_metrics(struct sock *sk) | |||
755 | } | 765 | } |
756 | } | 766 | } |
757 | 767 | ||
758 | /* Numbers are taken from RFC2414. */ | 768 | /* Numbers are taken from RFC3390. |
769 | * | ||
770 | * John Heffner states: | ||
771 | * | ||
772 | * The RFC specifies a window of no more than 4380 bytes | ||
773 | * unless 2*MSS > 4380. Reading the pseudocode in the RFC | ||
774 | * is a bit misleading because they use a clamp at 4380 bytes | ||
775 | * rather than use a multiplier in the relevant range. | ||
776 | */ | ||
759 | __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst) | 777 | __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst) |
760 | { | 778 | { |
761 | __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0); | 779 | __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0); |
@@ -2402,6 +2420,9 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb, | |||
2402 | __u32 dval = min(tp->fackets_out, packets_acked); | 2420 | __u32 dval = min(tp->fackets_out, packets_acked); |
2403 | tp->fackets_out -= dval; | 2421 | tp->fackets_out -= dval; |
2404 | } | 2422 | } |
2423 | /* hint's skb might be NULL but we don't need to care */ | ||
2424 | tp->fastpath_cnt_hint -= min_t(u32, packets_acked, | ||
2425 | tp->fastpath_cnt_hint); | ||
2405 | tp->packets_out -= packets_acked; | 2426 | tp->packets_out -= packets_acked; |
2406 | 2427 | ||
2407 | BUG_ON(tcp_skb_pcount(skb) == 0); | 2428 | BUG_ON(tcp_skb_pcount(skb) == 0); |