diff options
author | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2008-09-04 01:30:19 -0400 |
---|---|---|
committer | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2008-09-04 01:45:42 -0400 |
commit | 88e97a93342c0b9e835d510921e7b2df8547d1bd (patch) | |
tree | 0e8406050b02487b213b062f4d37528051f465e3 /net/dccp/ccids | |
parent | 68c89ee53571a441799c03d5e240c6441bced620 (diff) |
dccp ccid-3: Update the RX history records in one place
This patch is a requirement for enabling ECN support later on. With that change
in mind, the following preparations are done:
* renamed handle_loss() into congestion_event() since it returns true when a
congestion event happens (it will eventually also take care of ECN packets);
* lets tfrc_rx_congestion_event() always update the RX history records, since
this routine needs to be called for each non-duplicate packet anyway;
* made all involved boolean-type functions to have return type `bool';
Updating the RX history records is now only necessary for the packets received
up to sending the first feedback. The receiver code becomes again simpler.
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Diffstat (limited to 'net/dccp/ccids')
-rw-r--r-- | net/dccp/ccids/ccid3.c | 37 | ||||
-rw-r--r-- | net/dccp/ccids/lib/loss_interval.c | 10 | ||||
-rw-r--r-- | net/dccp/ccids/lib/loss_interval.h | 2 | ||||
-rw-r--r-- | net/dccp/ccids/lib/packet_history.c | 37 | ||||
-rw-r--r-- | net/dccp/ccids/lib/packet_history.h | 10 |
5 files changed, 40 insertions, 56 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index f2f9514dbad2..aca072b3edae 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -657,41 +657,26 @@ failed: | |||
657 | static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) | 657 | static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) |
658 | { | 658 | { |
659 | struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); | 659 | struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); |
660 | enum ccid3_fback_type do_feedback = CCID3_FBACK_NONE; | ||
661 | const u64 ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp; | 660 | const u64 ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp; |
662 | const bool is_data_packet = dccp_data_packet(skb); | 661 | const bool is_data_packet = dccp_data_packet(skb); |
663 | 662 | ||
664 | /* | 663 | /* |
665 | * Perform loss detection and handle pending losses | 664 | * Perform loss detection and handle pending losses |
666 | */ | 665 | */ |
667 | if (tfrc_rx_handle_loss(&hcrx->hist, &hcrx->li_hist, | 666 | if (tfrc_rx_congestion_event(&hcrx->hist, &hcrx->li_hist, |
668 | skb, ndp, ccid3_first_li, sk)) { | 667 | skb, ndp, ccid3_first_li, sk)) |
669 | do_feedback = CCID3_FBACK_PARAM_CHANGE; | 668 | ccid3_hc_rx_send_feedback(sk, skb, CCID3_FBACK_PARAM_CHANGE); |
670 | goto done_receiving; | 669 | /* |
671 | } | 670 | * Feedback for first non-empty data packet (RFC 3448, 6.3) |
672 | 671 | */ | |
673 | if (unlikely(hcrx->feedback == CCID3_FBACK_NONE)) { | 672 | else if (unlikely(hcrx->feedback == CCID3_FBACK_NONE && is_data_packet)) |
674 | if (is_data_packet) | 673 | ccid3_hc_rx_send_feedback(sk, skb, CCID3_FBACK_INITIAL); |
675 | do_feedback = CCID3_FBACK_INITIAL; | ||
676 | goto update_records; | ||
677 | } | ||
678 | |||
679 | if (tfrc_rx_hist_loss_pending(&hcrx->hist)) | ||
680 | return; /* done receiving */ | ||
681 | |||
682 | /* | 674 | /* |
683 | * Check if the periodic once-per-RTT feedback is due; RFC 4342, 10.3 | 675 | * Check if the periodic once-per-RTT feedback is due; RFC 4342, 10.3 |
684 | */ | 676 | */ |
685 | if (is_data_packet && | 677 | else if (!tfrc_rx_hist_loss_pending(&hcrx->hist) && is_data_packet && |
686 | SUB16(dccp_hdr(skb)->dccph_ccval, hcrx->last_counter) > 3) | 678 | SUB16(dccp_hdr(skb)->dccph_ccval, hcrx->last_counter) > 3) |
687 | do_feedback = CCID3_FBACK_PERIODIC; | 679 | ccid3_hc_rx_send_feedback(sk, skb, CCID3_FBACK_PERIODIC); |
688 | |||
689 | update_records: | ||
690 | tfrc_rx_hist_add_packet(&hcrx->hist, skb, ndp); | ||
691 | |||
692 | done_receiving: | ||
693 | if (do_feedback) | ||
694 | ccid3_hc_rx_send_feedback(sk, skb, do_feedback); | ||
695 | } | 680 | } |
696 | 681 | ||
697 | static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) | 682 | static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) |
diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c index fe5c2a31c770..b1ae8f8259e5 100644 --- a/net/dccp/ccids/lib/loss_interval.c +++ b/net/dccp/ccids/lib/loss_interval.c | |||
@@ -140,18 +140,18 @@ static inline u8 tfrc_lh_is_new_loss(struct tfrc_loss_interval *cur, | |||
140 | * @sk: Used by @calc_first_li in caller-specific way (subtyping) | 140 | * @sk: Used by @calc_first_li in caller-specific way (subtyping) |
141 | * Updates I_mean and returns 1 if a new interval has in fact been added to @lh. | 141 | * Updates I_mean and returns 1 if a new interval has in fact been added to @lh. |
142 | */ | 142 | */ |
143 | int tfrc_lh_interval_add(struct tfrc_loss_hist *lh, struct tfrc_rx_hist *rh, | 143 | bool tfrc_lh_interval_add(struct tfrc_loss_hist *lh, struct tfrc_rx_hist *rh, |
144 | u32 (*calc_first_li)(struct sock *), struct sock *sk) | 144 | u32 (*calc_first_li)(struct sock *), struct sock *sk) |
145 | { | 145 | { |
146 | struct tfrc_loss_interval *cur = tfrc_lh_peek(lh), *new; | 146 | struct tfrc_loss_interval *cur = tfrc_lh_peek(lh), *new; |
147 | 147 | ||
148 | if (cur != NULL && !tfrc_lh_is_new_loss(cur, tfrc_rx_hist_loss_prev(rh))) | 148 | if (cur != NULL && !tfrc_lh_is_new_loss(cur, tfrc_rx_hist_loss_prev(rh))) |
149 | return 0; | 149 | return false; |
150 | 150 | ||
151 | new = tfrc_lh_demand_next(lh); | 151 | new = tfrc_lh_demand_next(lh); |
152 | if (unlikely(new == NULL)) { | 152 | if (unlikely(new == NULL)) { |
153 | DCCP_CRIT("Cannot allocate/add loss record."); | 153 | DCCP_CRIT("Cannot allocate/add loss record."); |
154 | return 0; | 154 | return false; |
155 | } | 155 | } |
156 | 156 | ||
157 | new->li_seqno = tfrc_rx_hist_loss_prev(rh)->tfrchrx_seqno; | 157 | new->li_seqno = tfrc_rx_hist_loss_prev(rh)->tfrchrx_seqno; |
@@ -169,7 +169,7 @@ int tfrc_lh_interval_add(struct tfrc_loss_hist *lh, struct tfrc_rx_hist *rh, | |||
169 | 169 | ||
170 | tfrc_lh_calc_i_mean(lh); | 170 | tfrc_lh_calc_i_mean(lh); |
171 | } | 171 | } |
172 | return 1; | 172 | return true; |
173 | } | 173 | } |
174 | EXPORT_SYMBOL_GPL(tfrc_lh_interval_add); | 174 | EXPORT_SYMBOL_GPL(tfrc_lh_interval_add); |
175 | 175 | ||
diff --git a/net/dccp/ccids/lib/loss_interval.h b/net/dccp/ccids/lib/loss_interval.h index f101ae2cf528..d08a226db43e 100644 --- a/net/dccp/ccids/lib/loss_interval.h +++ b/net/dccp/ccids/lib/loss_interval.h | |||
@@ -67,7 +67,7 @@ static inline u8 tfrc_lh_length(struct tfrc_loss_hist *lh) | |||
67 | 67 | ||
68 | struct tfrc_rx_hist; | 68 | struct tfrc_rx_hist; |
69 | 69 | ||
70 | extern int tfrc_lh_interval_add(struct tfrc_loss_hist *, struct tfrc_rx_hist *, | 70 | extern bool tfrc_lh_interval_add(struct tfrc_loss_hist *, struct tfrc_rx_hist *, |
71 | u32 (*first_li)(struct sock *), struct sock *); | 71 | u32 (*first_li)(struct sock *), struct sock *); |
72 | extern void tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *); | 72 | extern void tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *); |
73 | extern void tfrc_lh_cleanup(struct tfrc_loss_hist *lh); | 73 | extern void tfrc_lh_cleanup(struct tfrc_loss_hist *lh); |
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c index 547ad098ea6a..cce9f03bda3e 100644 --- a/net/dccp/ccids/lib/packet_history.c +++ b/net/dccp/ccids/lib/packet_history.c | |||
@@ -192,10 +192,8 @@ static void __do_track_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u64 n1) | |||
192 | u64 s0 = tfrc_rx_hist_loss_prev(h)->tfrchrx_seqno, | 192 | u64 s0 = tfrc_rx_hist_loss_prev(h)->tfrchrx_seqno, |
193 | s1 = DCCP_SKB_CB(skb)->dccpd_seq; | 193 | s1 = DCCP_SKB_CB(skb)->dccpd_seq; |
194 | 194 | ||
195 | if (!dccp_loss_free(s0, s1, n1)) { /* gap between S0 and S1 */ | 195 | if (!dccp_loss_free(s0, s1, n1)) /* gap between S0 and S1 */ |
196 | h->loss_count = 1; | 196 | h->loss_count = 1; |
197 | tfrc_rx_hist_entry_from_skb(tfrc_rx_hist_entry(h, 1), skb, n1); | ||
198 | } | ||
199 | } | 197 | } |
200 | 198 | ||
201 | static void __one_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n2) | 199 | static void __one_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n2) |
@@ -328,13 +326,13 @@ static void __three_after_loss(struct tfrc_rx_hist *h) | |||
328 | } | 326 | } |
329 | 327 | ||
330 | /** | 328 | /** |
331 | * tfrc_rx_handle_loss - Loss detection and further processing | 329 | * tfrc_rx_congestion_event - Loss detection and further processing |
332 | * @h: The non-empty RX history object | 330 | * @h: The non-empty RX history object |
333 | * @lh: Loss Intervals database to update | 331 | * @lh: Loss Intervals database to update |
334 | * @skb: Currently received packet | 332 | * @skb: Currently received packet |
335 | * @ndp: The NDP count belonging to @skb | 333 | * @ndp: The NDP count belonging to @skb |
336 | * @calc_first_li: Caller-dependent computation of first loss interval in @lh | 334 | * @first_li: Caller-dependent computation of first loss interval in @lh |
337 | * @sk: Used by @calc_first_li (see tfrc_lh_interval_add) | 335 | * @sk: Used by @calc_first_li (see tfrc_lh_interval_add) |
338 | * Chooses action according to pending loss, updates LI database when a new | 336 | * Chooses action according to pending loss, updates LI database when a new |
339 | * loss was detected, and does required post-processing. Returns 1 when caller | 337 | * loss was detected, and does required post-processing. Returns 1 when caller |
340 | * should send feedback, 0 otherwise. | 338 | * should send feedback, 0 otherwise. |
@@ -342,12 +340,12 @@ static void __three_after_loss(struct tfrc_rx_hist *h) | |||
342 | * records accordingly, the caller should not perform any more RX history | 340 | * records accordingly, the caller should not perform any more RX history |
343 | * operations when loss_count is greater than 0 after calling this function. | 341 | * operations when loss_count is greater than 0 after calling this function. |
344 | */ | 342 | */ |
345 | int tfrc_rx_handle_loss(struct tfrc_rx_hist *h, | 343 | bool tfrc_rx_congestion_event(struct tfrc_rx_hist *h, |
346 | struct tfrc_loss_hist *lh, | 344 | struct tfrc_loss_hist *lh, |
347 | struct sk_buff *skb, const u64 ndp, | 345 | struct sk_buff *skb, const u64 ndp, |
348 | u32 (*calc_first_li)(struct sock *), struct sock *sk) | 346 | u32 (*first_li)(struct sock *), struct sock *sk) |
349 | { | 347 | { |
350 | int is_new_loss = 0; | 348 | bool new_event = false; |
351 | 349 | ||
352 | if (tfrc_rx_hist_duplicate(h, skb)) | 350 | if (tfrc_rx_hist_duplicate(h, skb)) |
353 | return 0; | 351 | return 0; |
@@ -355,6 +353,7 @@ int tfrc_rx_handle_loss(struct tfrc_rx_hist *h, | |||
355 | if (h->loss_count == 0) { | 353 | if (h->loss_count == 0) { |
356 | __do_track_loss(h, skb, ndp); | 354 | __do_track_loss(h, skb, ndp); |
357 | tfrc_rx_hist_sample_rtt(h, skb); | 355 | tfrc_rx_hist_sample_rtt(h, skb); |
356 | tfrc_rx_hist_add_packet(h, skb, ndp); | ||
358 | } else if (h->loss_count == 1) { | 357 | } else if (h->loss_count == 1) { |
359 | __one_after_loss(h, skb, ndp); | 358 | __one_after_loss(h, skb, ndp); |
360 | } else if (h->loss_count != 2) { | 359 | } else if (h->loss_count != 2) { |
@@ -363,7 +362,7 @@ int tfrc_rx_handle_loss(struct tfrc_rx_hist *h, | |||
363 | /* | 362 | /* |
364 | * Update Loss Interval database and recycle RX records | 363 | * Update Loss Interval database and recycle RX records |
365 | */ | 364 | */ |
366 | is_new_loss = tfrc_lh_interval_add(lh, h, calc_first_li, sk); | 365 | new_event = tfrc_lh_interval_add(lh, h, first_li, sk); |
367 | __three_after_loss(h); | 366 | __three_after_loss(h); |
368 | } | 367 | } |
369 | 368 | ||
@@ -378,12 +377,12 @@ int tfrc_rx_handle_loss(struct tfrc_rx_hist *h, | |||
378 | } | 377 | } |
379 | 378 | ||
380 | /* RFC 3448, 6.1: update I_0, whose growth implies p <= p_prev */ | 379 | /* RFC 3448, 6.1: update I_0, whose growth implies p <= p_prev */ |
381 | if (!is_new_loss) | 380 | if (!new_event) |
382 | tfrc_lh_update_i_mean(lh, skb); | 381 | tfrc_lh_update_i_mean(lh, skb); |
383 | 382 | ||
384 | return is_new_loss; | 383 | return new_event; |
385 | } | 384 | } |
386 | EXPORT_SYMBOL_GPL(tfrc_rx_handle_loss); | 385 | EXPORT_SYMBOL_GPL(tfrc_rx_congestion_event); |
387 | 386 | ||
388 | /* Compute the sending rate X_recv measured between feedback intervals */ | 387 | /* Compute the sending rate X_recv measured between feedback intervals */ |
389 | u32 tfrc_rx_hist_x_recv(struct tfrc_rx_hist *h, const u32 last_x_recv) | 388 | u32 tfrc_rx_hist_x_recv(struct tfrc_rx_hist *h, const u32 last_x_recv) |
diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h index 6552be63cb0a..555e65cd73a0 100644 --- a/net/dccp/ccids/lib/packet_history.h +++ b/net/dccp/ccids/lib/packet_history.h | |||
@@ -186,11 +186,11 @@ extern void tfrc_rx_hist_add_packet(struct tfrc_rx_hist *h, | |||
186 | extern int tfrc_rx_hist_duplicate(struct tfrc_rx_hist *h, struct sk_buff *skb); | 186 | extern int tfrc_rx_hist_duplicate(struct tfrc_rx_hist *h, struct sk_buff *skb); |
187 | 187 | ||
188 | struct tfrc_loss_hist; | 188 | struct tfrc_loss_hist; |
189 | extern int tfrc_rx_handle_loss(struct tfrc_rx_hist *h, | 189 | extern bool tfrc_rx_congestion_event(struct tfrc_rx_hist *h, |
190 | struct tfrc_loss_hist *lh, | 190 | struct tfrc_loss_hist *lh, |
191 | struct sk_buff *skb, const u64 ndp, | 191 | struct sk_buff *skb, const u64 ndp, |
192 | u32 (*first_li)(struct sock *sk), | 192 | u32 (*first_li)(struct sock *sk), |
193 | struct sock *sk); | 193 | struct sock *sk); |
194 | extern void tfrc_rx_hist_sample_rtt(struct tfrc_rx_hist *h, | 194 | extern void tfrc_rx_hist_sample_rtt(struct tfrc_rx_hist *h, |
195 | const struct sk_buff *skb); | 195 | const struct sk_buff *skb); |
196 | extern int tfrc_rx_hist_init(struct tfrc_rx_hist *h, struct sock *sk); | 196 | extern int tfrc_rx_hist_init(struct tfrc_rx_hist *h, struct sock *sk); |