diff options
| author | David S. Miller <davem@davemloft.net> | 2011-03-15 15:15:17 -0700 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-03-15 15:15:17 -0700 | 
| commit | c337ffb68e1e71bad069b14d2246fa1e0c31699c (patch) | |
| tree | 7861a59b196adfd63758cc0921e4fb56030fbaf3 /net/ipv4/tcp_cubic.c | |
| parent | 30df754dedebf27ef90452944a723ba058d23396 (diff) | |
| parent | 84c0c6933cb0303fa006992a6659c2b46de4eb17 (diff) | |
| download | olio-linux-3.10-c337ffb68e1e71bad069b14d2246fa1e0c31699c.tar.xz olio-linux-3.10-c337ffb68e1e71bad069b14d2246fa1e0c31699c.zip  | |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'net/ipv4/tcp_cubic.c')
| -rw-r--r-- | net/ipv4/tcp_cubic.c | 45 | 
1 files changed, 34 insertions, 11 deletions
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c index 62f775cb086..34340c9c95f 100644 --- a/net/ipv4/tcp_cubic.c +++ b/net/ipv4/tcp_cubic.c @@ -39,7 +39,7 @@  /* Number of delay samples for detecting the increase of delay */  #define HYSTART_MIN_SAMPLES	8 -#define HYSTART_DELAY_MIN	(2U<<3) +#define HYSTART_DELAY_MIN	(4U<<3)  #define HYSTART_DELAY_MAX	(16U<<3)  #define HYSTART_DELAY_THRESH(x)	clamp(x, HYSTART_DELAY_MIN, HYSTART_DELAY_MAX) @@ -52,6 +52,7 @@ static int tcp_friendliness __read_mostly = 1;  static int hystart __read_mostly = 1;  static int hystart_detect __read_mostly = HYSTART_ACK_TRAIN | HYSTART_DELAY;  static int hystart_low_window __read_mostly = 16; +static int hystart_ack_delta __read_mostly = 2;  static u32 cube_rtt_scale __read_mostly;  static u32 beta_scale __read_mostly; @@ -75,6 +76,8 @@ MODULE_PARM_DESC(hystart_detect, "hyrbrid slow start detection mechanisms"  		 " 1: packet-train 2: delay 3: both packet-train and delay");  module_param(hystart_low_window, int, 0644);  MODULE_PARM_DESC(hystart_low_window, "lower bound cwnd for hybrid slow start"); +module_param(hystart_ack_delta, int, 0644); +MODULE_PARM_DESC(hystart_ack_delta, "spacing between ack's indicating train (msecs)");  /* BIC TCP Parameters */  struct bictcp { @@ -85,7 +88,7 @@ struct bictcp {  	u32	last_time;	/* time when updated last_cwnd */  	u32	bic_origin_point;/* origin point of bic function */  	u32	bic_K;		/* time to origin point from the beginning of the current epoch */ -	u32	delay_min;	/* min delay */ +	u32	delay_min;	/* min delay (msec << 3) */  	u32	epoch_start;	/* beginning of an epoch */  	u32	ack_cnt;	/* number of acks */  	u32	tcp_cwnd;	/* estimated tcp cwnd */ @@ -95,7 +98,7 @@ struct bictcp {  	u8	found;		/* the exit point is found? */  	u32	round_start;	/* beginning of each round */  	u32	end_seq;	/* end_seq of the round */ -	u32	last_jiffies;	/* last time when the ACK spacing is close */ +	u32	last_ack;	/* last time when the ACK spacing is close */  	u32	curr_rtt;	/* the minimum rtt of current round */  }; @@ -116,12 +119,21 @@ static inline void bictcp_reset(struct bictcp *ca)  	ca->found = 0;  } +static inline u32 bictcp_clock(void) +{ +#if HZ < 1000 +	return ktime_to_ms(ktime_get_real()); +#else +	return jiffies_to_msecs(jiffies); +#endif +} +  static inline void bictcp_hystart_reset(struct sock *sk)  {  	struct tcp_sock *tp = tcp_sk(sk);  	struct bictcp *ca = inet_csk_ca(sk); -	ca->round_start = ca->last_jiffies = jiffies; +	ca->round_start = ca->last_ack = bictcp_clock();  	ca->end_seq = tp->snd_nxt;  	ca->curr_rtt = 0;  	ca->sample_cnt = 0; @@ -236,8 +248,8 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)  	 */  	/* change the unit from HZ to bictcp_HZ */ -	t = ((tcp_time_stamp + (ca->delay_min>>3) - ca->epoch_start) -	     << BICTCP_HZ) / HZ; +	t = ((tcp_time_stamp + msecs_to_jiffies(ca->delay_min>>3) +	      - ca->epoch_start) << BICTCP_HZ) / HZ;  	if (t < ca->bic_K)		/* t - K */  		offs = ca->bic_K - t; @@ -258,6 +270,13 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)  		ca->cnt = 100 * cwnd;              /* very small increment*/  	} +	/* +	 * The initial growth of cubic function may be too conservative +	 * when the available bandwidth is still unknown. +	 */ +	if (ca->loss_cwnd == 0 && ca->cnt > 20) +		ca->cnt = 20;	/* increase cwnd 5% per RTT */ +  	/* TCP Friendly */  	if (tcp_friendliness) {  		u32 scale = beta_scale; @@ -339,12 +358,12 @@ static void hystart_update(struct sock *sk, u32 delay)  	struct bictcp *ca = inet_csk_ca(sk);  	if (!(ca->found & hystart_detect)) { -		u32 curr_jiffies = jiffies; +		u32 now = bictcp_clock();  		/* first detection parameter - ack-train detection */ -		if (curr_jiffies - ca->last_jiffies <= msecs_to_jiffies(2)) { -			ca->last_jiffies = curr_jiffies; -			if (curr_jiffies - ca->round_start >= ca->delay_min>>4) +		if ((s32)(now - ca->last_ack) <= hystart_ack_delta) { +			ca->last_ack = now; +			if ((s32)(now - ca->round_start) > ca->delay_min >> 4)  				ca->found |= HYSTART_ACK_TRAIN;  		} @@ -391,7 +410,7 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us)  	if ((s32)(tcp_time_stamp - ca->epoch_start) < HZ)  		return; -	delay = usecs_to_jiffies(rtt_us) << 3; +	delay = (rtt_us << 3) / USEC_PER_MSEC;  	if (delay == 0)  		delay = 1; @@ -447,6 +466,10 @@ static int __init cubictcp_register(void)  	/* divide by bic_scale and by constant Srtt (100ms) */  	do_div(cube_factor, bic_scale * 10); +	/* hystart needs ms clock resolution */ +	if (hystart && HZ < 1000) +		cubictcp.flags |= TCP_CONG_RTT_STAMP; +  	return tcp_register_congestion_control(&cubictcp);  }  |