aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-08-31 01:10:28 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-08-31 01:10:28 -0400
commit05bb1fad1cde025a864a90cfeb98dcbefe78a44a (patch)
treed4146d601e960599a5a1249317beb45692619396
parent378be2c08314fc46e3f814fa264ff8ebdb79712f (diff)
[TCP]: Allow minimum RTO to be configurable via routing metrics.
Cell phone networks do link layer retransmissions and other things that cause unnecessary timeout retransmits. So allow the minimum RTO to be inflated per-route to deal with this. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/rtnetlink.h2
-rw-r--r--net/ipv4/tcp_input.c14
2 files changed, 14 insertions, 2 deletions
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index c91476ce314a..dff3192374f8 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -351,6 +351,8 @@ enum
351#define RTAX_INITCWND RTAX_INITCWND 351#define RTAX_INITCWND RTAX_INITCWND
352 RTAX_FEATURES, 352 RTAX_FEATURES,
353#define RTAX_FEATURES RTAX_FEATURES 353#define RTAX_FEATURES RTAX_FEATURES
354 RTAX_RTO_MIN,
355#define RTAX_RTO_MIN RTAX_RTO_MIN
354 __RTAX_MAX 356 __RTAX_MAX
355}; 357};
356 358
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 9785df37a65f..1ee72127462b 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
558static 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_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}