diff options
| author | Frederic Weisbecker <fweisbec@gmail.com> | 2013-05-02 17:37:49 +0200 | 
|---|---|---|
| committer | Frederic Weisbecker <fweisbec@gmail.com> | 2013-05-02 17:54:19 +0200 | 
| commit | c032862fba51a3ca504752d3a25186b324c5ce83 (patch) | |
| tree | 955dc2ba4ab3df76ecc2bb780ee84aca04967e8d /net/ipv4/tcp_input.c | |
| parent | fda76e074c7737fc57855dd17c762e50ed526052 (diff) | |
| parent | 8700c95adb033843fc163d112b9d21d4fda78018 (diff) | |
| download | olio-linux-3.10-c032862fba51a3ca504752d3a25186b324c5ce83.tar.xz olio-linux-3.10-c032862fba51a3ca504752d3a25186b324c5ce83.zip  | |
Merge commit '8700c95adb03' into timers/nohz
The full dynticks tree needs the latest RCU and sched
upstream updates in order to fix some dependencies.
Merge a common upstream merge point that has these
updates.
Conflicts:
	include/linux/perf_event.h
	kernel/rcutree.h
	kernel/rcutree_plugin.h
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'net/ipv4/tcp_input.c')
| -rw-r--r-- | net/ipv4/tcp_input.c | 77 | 
1 files changed, 36 insertions, 41 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index a759e19496d..13b9c08fc15 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -113,6 +113,7 @@ int sysctl_tcp_early_retrans __read_mostly = 2;  #define FLAG_DSACKING_ACK	0x800 /* SACK blocks contained D-SACK info */  #define FLAG_NONHEAD_RETRANS_ACKED	0x1000 /* Non-head rexmitted data was ACKed */  #define FLAG_SACK_RENEGING	0x2000 /* snd_una advanced to a sacked seq */ +#define FLAG_UPDATE_TS_RECENT	0x4000 /* tcp_replace_ts_recent() */  #define FLAG_ACKED		(FLAG_DATA_ACKED|FLAG_SYN_ACKED)  #define FLAG_NOT_DUP		(FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) @@ -2059,11 +2060,8 @@ void tcp_enter_loss(struct sock *sk, int how)  	if (tcp_is_reno(tp))  		tcp_reset_reno_sack(tp); -	if (!how) { -		/* Push undo marker, if it was plain RTO and nothing -		 * was retransmitted. */ -		tp->undo_marker = tp->snd_una; -	} else { +	tp->undo_marker = tp->snd_una; +	if (how) {  		tp->sacked_out = 0;  		tp->fackets_out = 0;  	} @@ -3567,6 +3565,27 @@ static void tcp_send_challenge_ack(struct sock *sk)  	}  } +static void tcp_store_ts_recent(struct tcp_sock *tp) +{ +	tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; +	tp->rx_opt.ts_recent_stamp = get_seconds(); +} + +static void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq) +{ +	if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) { +		/* PAWS bug workaround wrt. ACK frames, the PAWS discard +		 * extra check below makes sure this can only happen +		 * for pure ACK frames.  -DaveM +		 * +		 * Not only, also it occurs for expired timestamps. +		 */ + +		if (tcp_paws_check(&tp->rx_opt, 0)) +			tcp_store_ts_recent(tp); +	} +} +  /* This routine deals with incoming acks, but not outgoing ones. */  static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)  { @@ -3610,6 +3629,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)  	prior_fackets = tp->fackets_out;  	prior_in_flight = tcp_packets_in_flight(tp); +	/* ts_recent update must be made after we are sure that the packet +	 * is in window. +	 */ +	if (flag & FLAG_UPDATE_TS_RECENT) +		tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); +  	if (!(flag & FLAG_SLOWPATH) && after(ack, prior_snd_una)) {  		/* Window is constant, pure forward advance.  		 * No more checks are required. @@ -3930,27 +3955,6 @@ const u8 *tcp_parse_md5sig_option(const struct tcphdr *th)  EXPORT_SYMBOL(tcp_parse_md5sig_option);  #endif -static inline void tcp_store_ts_recent(struct tcp_sock *tp) -{ -	tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; -	tp->rx_opt.ts_recent_stamp = get_seconds(); -} - -static inline void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq) -{ -	if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) { -		/* PAWS bug workaround wrt. ACK frames, the PAWS discard -		 * extra check below makes sure this can only happen -		 * for pure ACK frames.  -DaveM -		 * -		 * Not only, also it occurs for expired timestamps. -		 */ - -		if (tcp_paws_check(&tp->rx_opt, 0)) -			tcp_store_ts_recent(tp); -	} -} -  /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM   *   * It is not fatal. If this ACK does _not_ change critical state (seqs, window) @@ -5485,6 +5489,9 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,  				if (tcp_checksum_complete_user(sk, skb))  					goto csum_error; +				if ((int)skb->truesize > sk->sk_forward_alloc) +					goto step5; +  				/* Predicted packet is in window by definition.  				 * seq == rcv_nxt and rcv_wup <= rcv_nxt.  				 * Hence, check seq<=rcv_wup reduces to: @@ -5496,9 +5503,6 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,  				tcp_rcv_rtt_measure_ts(sk, skb); -				if ((int)skb->truesize > sk->sk_forward_alloc) -					goto step5; -  				NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPHPHITS);  				/* Bulk data transfer: receiver */ @@ -5546,14 +5550,9 @@ slow_path:  		return 0;  step5: -	if (tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) +	if (tcp_ack(sk, skb, FLAG_SLOWPATH | FLAG_UPDATE_TS_RECENT) < 0)  		goto discard; -	/* ts_recent update must be made after we are sure that the packet -	 * is in window. -	 */ -	tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); -  	tcp_rcv_rtt_measure_ts(sk, skb);  	/* Process urgent data. */ @@ -5989,7 +5988,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,  	/* step 5: check the ACK field */  	if (true) { -		int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH) > 0; +		int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH | +						  FLAG_UPDATE_TS_RECENT) > 0;  		switch (sk->sk_state) {  		case TCP_SYN_RECV: @@ -6140,11 +6140,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,  		}  	} -	/* ts_recent update must be made after we are sure that the packet -	 * is in window. -	 */ -	tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); -  	/* step 6: check the URG bit */  	tcp_urg(sk, skb, th);  |