aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2008-09-04 01:30:19 -0400
committerGerrit Renker <gerrit@erg.abdn.ac.uk>2008-09-04 01:45:42 -0400
commit88e97a93342c0b9e835d510921e7b2df8547d1bd (patch)
tree0e8406050b02487b213b062f4d37528051f465e3
parent68c89ee53571a441799c03d5e240c6441bced620 (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>
-rw-r--r--net/dccp/ccids/ccid3.c37
-rw-r--r--net/dccp/ccids/lib/loss_interval.c10
-rw-r--r--net/dccp/ccids/lib/loss_interval.h2
-rw-r--r--net/dccp/ccids/lib/packet_history.c37
-rw-r--r--net/dccp/ccids/lib/packet_history.h10
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:
657static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) 657static 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
689update_records:
690 tfrc_rx_hist_add_packet(&hcrx->hist, skb, ndp);
691
692done_receiving:
693 if (do_feedback)
694 ccid3_hc_rx_send_feedback(sk, skb, do_feedback);
695} 680}
696 681
697static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) 682static 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 */
143int tfrc_lh_interval_add(struct tfrc_loss_hist *lh, struct tfrc_rx_hist *rh, 143bool 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}
174EXPORT_SYMBOL_GPL(tfrc_lh_interval_add); 174EXPORT_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
68struct tfrc_rx_hist; 68struct tfrc_rx_hist;
69 69
70extern int tfrc_lh_interval_add(struct tfrc_loss_hist *, struct tfrc_rx_hist *, 70extern 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 *);
72extern void tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *); 72extern void tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *);
73extern void tfrc_lh_cleanup(struct tfrc_loss_hist *lh); 73extern 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
201static void __one_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n2) 199static 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 */
345int tfrc_rx_handle_loss(struct tfrc_rx_hist *h, 343bool 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}
386EXPORT_SYMBOL_GPL(tfrc_rx_handle_loss); 385EXPORT_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 */
389u32 tfrc_rx_hist_x_recv(struct tfrc_rx_hist *h, const u32 last_x_recv) 388u32 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,
186extern int tfrc_rx_hist_duplicate(struct tfrc_rx_hist *h, struct sk_buff *skb); 186extern int tfrc_rx_hist_duplicate(struct tfrc_rx_hist *h, struct sk_buff *skb);
187 187
188struct tfrc_loss_hist; 188struct tfrc_loss_hist;
189extern int tfrc_rx_handle_loss(struct tfrc_rx_hist *h, 189extern 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);
194extern void tfrc_rx_hist_sample_rtt(struct tfrc_rx_hist *h, 194extern void tfrc_rx_hist_sample_rtt(struct tfrc_rx_hist *h,
195 const struct sk_buff *skb); 195 const struct sk_buff *skb);
196extern int tfrc_rx_hist_init(struct tfrc_rx_hist *h, struct sock *sk); 196extern int tfrc_rx_hist_init(struct tfrc_rx_hist *h, struct sock *sk);