aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2008-06-19 17:59:13 -0400
committerVlad Yasevich <vladislav.yasevich@hp.com>2008-10-01 11:33:06 -0400
commit2cd9b822bfa79fc1335d3e71a0449f3cd0b5078e (patch)
tree830f284cbc2f3be60e80705764f6dd6e84511188
parentbcd41303f422015ab662c9276d108414aa75b796 (diff)
sctp: Only mark chunks as missing when there are gaps
Frist small step in optimizing SACK processing. Do not call sctp_mark_missing() when there are no gaps reported and thus not missing chunks. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
-rw-r--r--net/sctp/outqueue.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 4328ad5439c9..ef5ea7423cc8 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -1129,12 +1129,13 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1129 unsigned outstanding; 1129 unsigned outstanding;
1130 struct sctp_transport *primary = asoc->peer.primary_path; 1130 struct sctp_transport *primary = asoc->peer.primary_path;
1131 int count_of_newacks = 0; 1131 int count_of_newacks = 0;
1132 int gap_ack_blocks;
1132 1133
1133 /* Grab the association's destination address list. */ 1134 /* Grab the association's destination address list. */
1134 transport_list = &asoc->peer.transport_addr_list; 1135 transport_list = &asoc->peer.transport_addr_list;
1135 1136
1136 sack_ctsn = ntohl(sack->cum_tsn_ack); 1137 sack_ctsn = ntohl(sack->cum_tsn_ack);
1137 1138 gap_ack_blocks = ntohs(sack->num_gap_ack_blocks);
1138 /* 1139 /*
1139 * SFR-CACC algorithm: 1140 * SFR-CACC algorithm:
1140 * On receipt of a SACK the sender SHOULD execute the 1141 * On receipt of a SACK the sender SHOULD execute the
@@ -1161,7 +1162,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1161 * A) Initialize the cacc_saw_newack to 0 for all destination 1162 * A) Initialize the cacc_saw_newack to 0 for all destination
1162 * addresses. 1163 * addresses.
1163 */ 1164 */
1164 if (sack->num_gap_ack_blocks && 1165 if (gap_ack_blocks &&
1165 primary->cacc.changeover_active) { 1166 primary->cacc.changeover_active) {
1166 list_for_each_entry(transport, transport_list, transports) { 1167 list_for_each_entry(transport, transport_list, transports) {
1167 transport->cacc.cacc_saw_newack = 0; 1168 transport->cacc.cacc_saw_newack = 0;
@@ -1170,9 +1171,8 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1170 1171
1171 /* Get the highest TSN in the sack. */ 1172 /* Get the highest TSN in the sack. */
1172 highest_tsn = sack_ctsn; 1173 highest_tsn = sack_ctsn;
1173 if (sack->num_gap_ack_blocks) 1174 if (gap_ack_blocks)
1174 highest_tsn += 1175 highest_tsn += ntohs(frags[gap_ack_blocks - 1].gab.end);
1175 ntohs(frags[ntohs(sack->num_gap_ack_blocks) - 1].gab.end);
1176 1176
1177 if (TSN_lt(asoc->highest_sacked, highest_tsn)) { 1177 if (TSN_lt(asoc->highest_sacked, highest_tsn)) {
1178 highest_new_tsn = highest_tsn; 1178 highest_new_tsn = highest_tsn;
@@ -1181,11 +1181,11 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1181 highest_new_tsn = sctp_highest_new_tsn(sack, asoc); 1181 highest_new_tsn = sctp_highest_new_tsn(sack, asoc);
1182 } 1182 }
1183 1183
1184
1184 /* Run through the retransmit queue. Credit bytes received 1185 /* Run through the retransmit queue. Credit bytes received
1185 * and free those chunks that we can. 1186 * and free those chunks that we can.
1186 */ 1187 */
1187 sctp_check_transmitted(q, &q->retransmit, NULL, sack, highest_new_tsn); 1188 sctp_check_transmitted(q, &q->retransmit, NULL, sack, highest_new_tsn);
1188 sctp_mark_missing(q, &q->retransmit, NULL, highest_new_tsn, 0);
1189 1189
1190 /* Run through the transmitted queue. 1190 /* Run through the transmitted queue.
1191 * Credit bytes received and free those chunks which we can. 1191 * Credit bytes received and free those chunks which we can.
@@ -1204,9 +1204,12 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1204 count_of_newacks ++; 1204 count_of_newacks ++;
1205 } 1205 }
1206 1206
1207 list_for_each_entry(transport, transport_list, transports) { 1207 if (gap_ack_blocks) {
1208 sctp_mark_missing(q, &transport->transmitted, transport, 1208 sctp_mark_missing(q, &q->retransmit, NULL, highest_new_tsn, 0);
1209 highest_new_tsn, count_of_newacks); 1209
1210 list_for_each_entry(transport, transport_list, transports)
1211 sctp_mark_missing(q, &transport->transmitted, transport,
1212 highest_new_tsn, count_of_newacks);
1210 } 1213 }
1211 1214
1212 /* Move the Cumulative TSN Ack Point if appropriate. */ 1215 /* Move the Cumulative TSN Ack Point if appropriate. */