aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>2007-10-10 05:45:32 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:55:51 -0400
commit1c1e87edb9aa38b9e1ae807a6d88fcfd350a55c0 (patch)
tree5021c683e1396ace6fd9d57daf09bb3a79c646d1 /net
parent5265eeb2b036835021591173ac64e624baaff55c (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')
-rw-r--r--net/ipv4/tcp_input.c80
1 files changed, 43 insertions, 37 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index e8c39488cf5..101054cb13e 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 */
1113static 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
1110static int tcp_check_dsack(struct tcp_sock *tp, struct sk_buff *ack_skb, 1151static 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