Commit 6d742fb6 authored by Ilpo Järvinen's avatar Ilpo Järvinen Committed by Greg Kroah-Hartman

Fix TCP DSACK cwnd handling

commit 49ff4bb4 in mainline.

[TCP]: DSACK signals data receival, be conservative

In case a DSACK is received, it's better to lower cwnd as it's
a sign of data receival.
Signed-off-by: default avatarIlpo Järvinen <ilpo.jarvinen@helsinki.fi>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent eb7bdad8
...@@ -103,6 +103,7 @@ int sysctl_tcp_abc __read_mostly; ...@@ -103,6 +103,7 @@ int sysctl_tcp_abc __read_mostly;
#define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ #define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/
#define FLAG_ONLY_ORIG_SACKED 0x200 /* SACKs only non-rexmit sent before RTO */ #define FLAG_ONLY_ORIG_SACKED 0x200 /* SACKs only non-rexmit sent before RTO */
#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ #define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */
#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained DSACK info */
#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED)
#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED)
...@@ -966,12 +967,14 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ ...@@ -966,12 +967,14 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
/* Check for D-SACK. */ /* Check for D-SACK. */
if (before(ntohl(sp[0].start_seq), TCP_SKB_CB(ack_skb)->ack_seq)) { if (before(ntohl(sp[0].start_seq), TCP_SKB_CB(ack_skb)->ack_seq)) {
flag |= FLAG_DSACKING_ACK;
found_dup_sack = 1; found_dup_sack = 1;
tp->rx_opt.sack_ok |= 4; tp->rx_opt.sack_ok |= 4;
NET_INC_STATS_BH(LINUX_MIB_TCPDSACKRECV); NET_INC_STATS_BH(LINUX_MIB_TCPDSACKRECV);
} else if (num_sacks > 1 && } else if (num_sacks > 1 &&
!after(ntohl(sp[0].end_seq), ntohl(sp[1].end_seq)) && !after(ntohl(sp[0].end_seq), ntohl(sp[1].end_seq)) &&
!before(ntohl(sp[0].start_seq), ntohl(sp[1].start_seq))) { !before(ntohl(sp[0].start_seq), ntohl(sp[1].start_seq))) {
flag |= FLAG_DSACKING_ACK;
found_dup_sack = 1; found_dup_sack = 1;
tp->rx_opt.sack_ok |= 4; tp->rx_opt.sack_ok |= 4;
NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFORECV); NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFORECV);
...@@ -1858,7 +1861,7 @@ static void tcp_cwnd_down(struct sock *sk, int flag) ...@@ -1858,7 +1861,7 @@ static void tcp_cwnd_down(struct sock *sk, int flag)
struct tcp_sock *tp = tcp_sk(sk); struct tcp_sock *tp = tcp_sk(sk);
int decr = tp->snd_cwnd_cnt + 1; int decr = tp->snd_cwnd_cnt + 1;
if ((flag&FLAG_ANY_PROGRESS) || if ((flag&(FLAG_ANY_PROGRESS|FLAG_DSACKING_ACK)) ||
(IsReno(tp) && !(flag&FLAG_NOT_DUP))) { (IsReno(tp) && !(flag&FLAG_NOT_DUP))) {
tp->snd_cwnd_cnt = decr&1; tp->snd_cwnd_cnt = decr&1;
decr >>= 1; decr >>= 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment