diff options
| author | David S. Miller <davem@nuts.davemloft.net> | 2004-04-21 09:10:52 -0700 |
|---|---|---|
| committer | David S. Miller <davem@nuts.davemloft.net> | 2004-04-21 09:10:52 -0700 |
| commit | 16a76bdbafd6c681dd15419183308bba1dd58063 (patch) | |
| tree | ecbd1f1877b7a48cb83842fec28bcb3d2e8e96ca /include | |
| parent | 91a793870dd95b4b337339de10b87803fce3433c (diff) | |
[TCP]: Add vegas congestion avoidance support.
A forward port of an old 2.3.x kernel hack done
years ago. I (DaveM) did the first rough port,
Stephen Hemminger actually cleaned it up and
made it usable.
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/sysctl.h | 4 | ||||
| -rw-r--r-- | include/linux/tcp.h | 12 | ||||
| -rw-r--r-- | include/net/tcp.h | 52 |
3 files changed, 68 insertions, 0 deletions
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index f32c83568201..46c9268c9079 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -327,6 +327,10 @@ enum NET_TCP_WESTWOOD=95, NET_IPV4_IGMP_MAX_MSF=96, NET_TCP_NO_METRICS_SAVE=97, + NET_TCP_VEGAS=98, + NET_TCP_VEGAS_ALPHA=99, + NET_TCP_VEGAS_BETA=100, + NET_TCP_VEGAS_GAMMA=101, }; enum { diff --git a/include/linux/tcp.h b/include/linux/tcp.h index f8c91e734737..00bece841380 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -388,6 +388,18 @@ struct tcp_opt { __u32 rtt; __u32 rtt_min; /* minimum observed RTT */ } westwood; + +/* Vegas variables */ + struct { + __u32 beg_snd_nxt; /* right edge during last RTT */ + __u32 beg_snd_una; /* left edge during last RTT */ + __u32 beg_snd_cwnd; /* saves the size of the cwnd */ + __u8 do_vegas; /* do vegas for this connection */ + __u8 doing_vegas_now;/* if true, do vegas for this RTT */ + __u16 cntRTT; /* # of RTTs measured within last RTT */ + __u32 minRTT; /* min of RTTs measured within last RTT (in usec) */ + __u32 baseRTT; /* the min of all Vegas RTT measurements seen (in usec) */ + } vegas; }; /* WARNING: don't change the layout of the members in tcp_sock! */ diff --git a/include/net/tcp.h b/include/net/tcp.h index af427a279038..076811e43c2c 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -583,6 +583,10 @@ extern int sysctl_tcp_tw_reuse; extern int sysctl_tcp_frto; extern int sysctl_tcp_low_latency; extern int sysctl_tcp_westwood; +extern int sysctl_tcp_vegas_cong_avoid; +extern int sysctl_tcp_vegas_alpha; +extern int sysctl_tcp_vegas_beta; +extern int sysctl_tcp_vegas_gamma; extern int sysctl_tcp_nometrics_save; extern atomic_t tcp_memory_allocated; @@ -1212,8 +1216,56 @@ static inline __u32 tcp_recalc_ssthresh(struct tcp_opt *tp) return max(tp->snd_cwnd >> 1U, 2U); } +/* Stop taking Vegas samples for now. */ +#define tcp_vegas_disable(__tp) ((__tp)->vegas.doing_vegas_now = 0) + +/* Is this TCP connection using Vegas (regardless of whether it is taking + * Vegas measurements at the current time)? + */ +#define tcp_is_vegas(__tp) ((__tp)->vegas.do_vegas) + +static inline void tcp_vegas_enable(struct tcp_opt *tp) +{ + /* There are several situations when we must "re-start" Vegas: + * + * o when a connection is established + * o after an RTO + * o after fast recovery + * o when we send a packet and there is no outstanding + * unacknowledged data (restarting an idle connection) + * + * In these circumstances we cannot do a Vegas calculation at the + * end of the first RTT, because any calculation we do is using + * stale info -- both the saved cwnd and congestion feedback are + * stale. + * + * Instead we must wait until the completion of an RTT during + * which we actually receive ACKs. + */ + + /* Begin taking Vegas samples next time we send something. */ + tp->vegas.doing_vegas_now = 1; + + /* Set the beginning of the next send window. */ + tp->vegas.beg_snd_nxt = tp->snd_nxt; + + tp->vegas.cntRTT = 0; + tp->vegas.minRTT = 0x7fffffff; +} + +/* Should we be taking Vegas samples right now? */ +#define tcp_vegas_enabled(__tp) ((__tp)->vegas.doing_vegas_now) + +extern void tcp_vegas_init(struct tcp_opt *tp); + static inline void tcp_set_ca_state(struct tcp_opt *tp, u8 ca_state) { + if (tcp_is_vegas(tp)) { + if (ca_state == TCP_CA_Open) + tcp_vegas_enable(tp); + else + tcp_vegas_disable(tp); + } tp->ca_state = ca_state; } |
