mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
tcp: sack lost marking fixes
When only fast rexmit should be done, tcp_mark_head_lost marks L too far. Also, sacked_upto below 1 is perfectly valid number, the packets == 0 then needs to be trapped elsewhere. Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f3e85df845
commit
1fdb936101
@ -2495,7 +2495,7 @@ static void tcp_timeout_skbs(struct sock *sk)
|
|||||||
/* Mark head of queue up as lost. With RFC3517 SACK, the packets is
|
/* Mark head of queue up as lost. With RFC3517 SACK, the packets is
|
||||||
* is against sacked "cnt", otherwise it's against facked "cnt"
|
* is against sacked "cnt", otherwise it's against facked "cnt"
|
||||||
*/
|
*/
|
||||||
static void tcp_mark_head_lost(struct sock *sk, int packets)
|
static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
|
||||||
{
|
{
|
||||||
struct tcp_sock *tp = tcp_sk(sk);
|
struct tcp_sock *tp = tcp_sk(sk);
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
@ -2503,13 +2503,13 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
|
|||||||
int err;
|
int err;
|
||||||
unsigned int mss;
|
unsigned int mss;
|
||||||
|
|
||||||
if (packets == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
WARN_ON(packets > tp->packets_out);
|
WARN_ON(packets > tp->packets_out);
|
||||||
if (tp->lost_skb_hint) {
|
if (tp->lost_skb_hint) {
|
||||||
skb = tp->lost_skb_hint;
|
skb = tp->lost_skb_hint;
|
||||||
cnt = tp->lost_cnt_hint;
|
cnt = tp->lost_cnt_hint;
|
||||||
|
/* Head already handled? */
|
||||||
|
if (mark_head && skb != tcp_write_queue_head(sk))
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
skb = tcp_write_queue_head(sk);
|
skb = tcp_write_queue_head(sk);
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
@ -2544,6 +2544,9 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tcp_skb_mark_lost(tp, skb);
|
tcp_skb_mark_lost(tp, skb);
|
||||||
|
|
||||||
|
if (mark_head)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
tcp_verify_left_out(tp);
|
tcp_verify_left_out(tp);
|
||||||
}
|
}
|
||||||
@ -2555,17 +2558,18 @@ static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit)
|
|||||||
struct tcp_sock *tp = tcp_sk(sk);
|
struct tcp_sock *tp = tcp_sk(sk);
|
||||||
|
|
||||||
if (tcp_is_reno(tp)) {
|
if (tcp_is_reno(tp)) {
|
||||||
tcp_mark_head_lost(sk, 1);
|
tcp_mark_head_lost(sk, 1, 1);
|
||||||
} else if (tcp_is_fack(tp)) {
|
} else if (tcp_is_fack(tp)) {
|
||||||
int lost = tp->fackets_out - tp->reordering;
|
int lost = tp->fackets_out - tp->reordering;
|
||||||
if (lost <= 0)
|
if (lost <= 0)
|
||||||
lost = 1;
|
lost = 1;
|
||||||
tcp_mark_head_lost(sk, lost);
|
tcp_mark_head_lost(sk, lost, 0);
|
||||||
} else {
|
} else {
|
||||||
int sacked_upto = tp->sacked_out - tp->reordering;
|
int sacked_upto = tp->sacked_out - tp->reordering;
|
||||||
if (sacked_upto < fast_rexmit)
|
if (sacked_upto >= 0)
|
||||||
sacked_upto = fast_rexmit;
|
tcp_mark_head_lost(sk, sacked_upto, 0);
|
||||||
tcp_mark_head_lost(sk, sacked_upto);
|
else if (fast_rexmit)
|
||||||
|
tcp_mark_head_lost(sk, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
tcp_timeout_skbs(sk);
|
tcp_timeout_skbs(sk);
|
||||||
@ -2971,7 +2975,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag)
|
|||||||
before(tp->snd_una, tp->high_seq) &&
|
before(tp->snd_una, tp->high_seq) &&
|
||||||
icsk->icsk_ca_state != TCP_CA_Open &&
|
icsk->icsk_ca_state != TCP_CA_Open &&
|
||||||
tp->fackets_out > tp->reordering) {
|
tp->fackets_out > tp->reordering) {
|
||||||
tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering);
|
tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering, 0);
|
||||||
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSS);
|
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user