diff options
author | Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> | 2007-10-10 05:45:32 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:55:51 -0400 |
commit | 1c1e87edb9aa38b9e1ae807a6d88fcfd350a55c0 (patch) | |
tree | 5021c683e1396ace6fd9d57daf09bb3a79c646d1 /net/ipv4/tcp_input.c | |
parent | 5265eeb2b036835021591173ac64e624baaff55c (diff) |
[TCP]: Separate lost_retrans loop into own function
Follows own function for each task principle, this is really
somewhat separate task being done in sacktag. Also reduces
indentation.
In addition, added ack_seq local var to break some long
lines & fixed coding style things.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 80 |
1 files changed, 43 insertions, 37 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e8c39488cf58..101054cb13e9 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -1106,6 +1106,47 @@ static int tcp_is_sackblock_valid(struct tcp_sock *tp, int is_dsack, | |||
1106 | return !before(start_seq, end_seq - tp->max_window); | 1106 | return !before(start_seq, end_seq - tp->max_window); |
1107 | } | 1107 | } |
1108 | 1108 | ||
1109 | /* Check for lost retransmit. This superb idea is borrowed from "ratehalving". | ||
1110 | * Event "C". Later note: FACK people cheated me again 8), we have to account | ||
1111 | * for reordering! Ugly, but should help. | ||
1112 | */ | ||
1113 | static int tcp_mark_lost_retrans(struct sock *sk, u32 lost_retrans) | ||
1114 | { | ||
1115 | struct tcp_sock *tp = tcp_sk(sk); | ||
1116 | struct sk_buff *skb; | ||
1117 | int flag = 0; | ||
1118 | |||
1119 | tcp_for_write_queue(skb, sk) { | ||
1120 | u32 ack_seq = TCP_SKB_CB(skb)->ack_seq; | ||
1121 | |||
1122 | if (skb == tcp_send_head(sk)) | ||
1123 | break; | ||
1124 | if (after(TCP_SKB_CB(skb)->seq, lost_retrans)) | ||
1125 | break; | ||
1126 | if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una)) | ||
1127 | continue; | ||
1128 | |||
1129 | if ((TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) && | ||
1130 | after(lost_retrans, ack_seq) && | ||
1131 | (tcp_is_fack(tp) || | ||
1132 | !before(lost_retrans, | ||
1133 | ack_seq + tp->reordering * tp->mss_cache))) { | ||
1134 | TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; | ||
1135 | tp->retrans_out -= tcp_skb_pcount(skb); | ||
1136 | |||
1137 | /* clear lost hint */ | ||
1138 | tp->retransmit_skb_hint = NULL; | ||
1139 | |||
1140 | if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_ACKED))) { | ||
1141 | tp->lost_out += tcp_skb_pcount(skb); | ||
1142 | TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; | ||
1143 | flag |= FLAG_DATA_SACKED; | ||
1144 | NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT); | ||
1145 | } | ||
1146 | } | ||
1147 | } | ||
1148 | return flag; | ||
1149 | } | ||
1109 | 1150 | ||
1110 | static int tcp_check_dsack(struct tcp_sock *tp, struct sk_buff *ack_skb, | 1151 | static int tcp_check_dsack(struct tcp_sock *tp, struct sk_buff *ack_skb, |
1111 | struct tcp_sack_block_wire *sp, int num_sacks, | 1152 | struct tcp_sack_block_wire *sp, int num_sacks, |
@@ -1422,43 +1463,8 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ | |||
1422 | } | 1463 | } |
1423 | } | 1464 | } |
1424 | 1465 | ||
1425 | /* Check for lost retransmit. This superb idea is | 1466 | if (lost_retrans && icsk->icsk_ca_state == TCP_CA_Recovery) |
1426 | * borrowed from "ratehalving". Event "C". | 1467 | flag |= tcp_mark_lost_retrans(sk, lost_retrans); |
1427 | * Later note: FACK people cheated me again 8), | ||
1428 | * we have to account for reordering! Ugly, | ||
1429 | * but should help. | ||
1430 | */ | ||
1431 | if (lost_retrans && icsk->icsk_ca_state == TCP_CA_Recovery) { | ||
1432 | struct sk_buff *skb; | ||
1433 | |||
1434 | tcp_for_write_queue(skb, sk) { | ||
1435 | if (skb == tcp_send_head(sk)) | ||
1436 | break; | ||
1437 | if (after(TCP_SKB_CB(skb)->seq, lost_retrans)) | ||
1438 | break; | ||
1439 | if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una)) | ||
1440 | continue; | ||
1441 | if ((TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS) && | ||
1442 | after(lost_retrans, TCP_SKB_CB(skb)->ack_seq) && | ||
1443 | (tcp_is_fack(tp) || | ||
1444 | !before(lost_retrans, | ||
1445 | TCP_SKB_CB(skb)->ack_seq + tp->reordering * | ||
1446 | tp->mss_cache))) { | ||
1447 | TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; | ||
1448 | tp->retrans_out -= tcp_skb_pcount(skb); | ||
1449 | |||
1450 | /* clear lost hint */ | ||
1451 | tp->retransmit_skb_hint = NULL; | ||
1452 | |||
1453 | if (!(TCP_SKB_CB(skb)->sacked&(TCPCB_LOST|TCPCB_SACKED_ACKED))) { | ||
1454 | tp->lost_out += tcp_skb_pcount(skb); | ||
1455 | TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; | ||
1456 | flag |= FLAG_DATA_SACKED; | ||
1457 | NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT); | ||
1458 | } | ||
1459 | } | ||
1460 | } | ||
1461 | } | ||
1462 | 1468 | ||
1463 | tcp_verify_left_out(tp); | 1469 | tcp_verify_left_out(tp); |
1464 | 1470 | ||