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:41 -0400 |
commit | 34a081be8e14b7ada70e069b65b05d54db4af497 (patch) | |
tree | 0304cc3c06e1ee9139d6dab01df07c8d073cd323 /net/dccp/ccids | |
parent | 3ca7aea04152255bb65275b0018d3c673bc1f4e7 (diff) |
dccp tfrc: Let dccp_tfrc_lib do the sampling work
This migrates more TFRC-related code into the dccp_tfrc_lib:
* sampling of the packet size `s' (which is only needed until the first
loss interval is computed (ccid3_first_li));
* updating the byte-counter `bytes_recvd' in between sending feedbacks.
The result is a better separation of CCID-3 specific and TFRC specific
code, which aids future integration with ECN and e.g. CCID-4.
Further changes:
----------------
* replaced magic number of 536 with equivalent constant TCP_MIN_RCVMSS;
(this constant is also used when no estimate for `s' is available).
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Diffstat (limited to 'net/dccp/ccids')
-rw-r--r-- | net/dccp/ccids/ccid3.c | 38 | ||||
-rw-r--r-- | net/dccp/ccids/ccid3.h | 4 | ||||
-rw-r--r-- | net/dccp/ccids/lib/packet_history.c | 10 | ||||
-rw-r--r-- | net/dccp/ccids/lib/packet_history.h | 16 |
4 files changed, 34 insertions, 34 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 50dac01e48c5..8744590acb34 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -590,12 +590,9 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk, | |||
590 | * would bring X down to s/t_mbi. That is why we return | 590 | * would bring X down to s/t_mbi. That is why we return |
591 | * X_recv according to rfc3448bis-06 for the moment. | 591 | * X_recv according to rfc3448bis-06 for the moment. |
592 | */ | 592 | */ |
593 | u32 rtt = hcrx->rtt ? : DCCP_FALLBACK_RTT, s = hcrx->s; | 593 | u32 rtt = hcrx->rtt ? : DCCP_FALLBACK_RTT, |
594 | s = tfrc_rx_hist_packet_size(&hcrx->hist); | ||
594 | 595 | ||
595 | if (s == 0) { | ||
596 | DCCP_WARN("No sample for s, using fallback\n"); | ||
597 | s = TCP_MIN_RCVMSS; | ||
598 | } | ||
599 | hcrx->x_recv = scaled_div32(s, 2 * rtt); | 596 | hcrx->x_recv = scaled_div32(s, 2 * rtt); |
600 | break; | 597 | break; |
601 | } | 598 | } |
@@ -617,7 +614,7 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk, | |||
617 | if (delta <= 0) | 614 | if (delta <= 0) |
618 | DCCP_BUG("delta (%ld) <= 0", (long)delta); | 615 | DCCP_BUG("delta (%ld) <= 0", (long)delta); |
619 | else | 616 | else |
620 | hcrx->x_recv = scaled_div32(hcrx->bytes_recv, delta); | 617 | hcrx->x_recv = scaled_div32(hcrx->hist.bytes_recvd, delta); |
621 | break; | 618 | break; |
622 | default: | 619 | default: |
623 | return; | 620 | return; |
@@ -628,7 +625,7 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk, | |||
628 | 625 | ||
629 | hcrx->tstamp_last_feedback = now; | 626 | hcrx->tstamp_last_feedback = now; |
630 | hcrx->last_counter = dccp_hdr(skb)->dccph_ccval; | 627 | hcrx->last_counter = dccp_hdr(skb)->dccph_ccval; |
631 | hcrx->bytes_recv = 0; | 628 | hcrx->hist.bytes_recvd = 0; |
632 | 629 | ||
633 | dp->dccps_hc_rx_insert_options = 1; | 630 | dp->dccps_hc_rx_insert_options = 1; |
634 | dccp_send_ack(sk); | 631 | dccp_send_ack(sk); |
@@ -669,7 +666,8 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) | |||
669 | static u32 ccid3_first_li(struct sock *sk) | 666 | static u32 ccid3_first_li(struct sock *sk) |
670 | { | 667 | { |
671 | struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); | 668 | struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); |
672 | u32 x_recv, p, delta; | 669 | u32 x_recv, p, delta, |
670 | s = tfrc_rx_hist_packet_size(&hcrx->hist); | ||
673 | u64 fval; | 671 | u64 fval; |
674 | 672 | ||
675 | /* | 673 | /* |
@@ -686,7 +684,7 @@ static u32 ccid3_first_li(struct sock *sk) | |||
686 | } | 684 | } |
687 | 685 | ||
688 | delta = ktime_to_us(net_timedelta(hcrx->tstamp_last_feedback)); | 686 | delta = ktime_to_us(net_timedelta(hcrx->tstamp_last_feedback)); |
689 | x_recv = scaled_div32(hcrx->bytes_recv, delta); | 687 | x_recv = scaled_div32(hcrx->hist.bytes_recvd, delta); |
690 | if (x_recv == 0) { /* would also trigger divide-by-zero */ | 688 | if (x_recv == 0) { /* would also trigger divide-by-zero */ |
691 | DCCP_WARN("X_recv==0\n"); | 689 | DCCP_WARN("X_recv==0\n"); |
692 | if (hcrx->x_recv == 0) { | 690 | if (hcrx->x_recv == 0) { |
@@ -696,8 +694,7 @@ static u32 ccid3_first_li(struct sock *sk) | |||
696 | x_recv = hcrx->x_recv; | 694 | x_recv = hcrx->x_recv; |
697 | } | 695 | } |
698 | 696 | ||
699 | fval = scaled_div(hcrx->s, hcrx->rtt); | 697 | fval = scaled_div32(scaled_div(s, hcrx->rtt), x_recv); |
700 | fval = scaled_div32(fval, x_recv); | ||
701 | p = tfrc_calc_x_reverse_lookup(fval); | 698 | p = tfrc_calc_x_reverse_lookup(fval); |
702 | 699 | ||
703 | ccid3_pr_debug("%s(%p), receive rate=%u bytes/s, implied " | 700 | ccid3_pr_debug("%s(%p), receive rate=%u bytes/s, implied " |
@@ -724,31 +721,12 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
724 | 721 | ||
725 | if (unlikely(hcrx->state == TFRC_RSTATE_NO_DATA)) { | 722 | if (unlikely(hcrx->state == TFRC_RSTATE_NO_DATA)) { |
726 | if (is_data_packet) { | 723 | if (is_data_packet) { |
727 | const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4; | ||
728 | do_feedback = CCID3_FBACK_INITIAL; | 724 | do_feedback = CCID3_FBACK_INITIAL; |
729 | ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA); | 725 | ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA); |
730 | hcrx->s = payload; | ||
731 | /* | ||
732 | * Not necessary to update bytes_recv here, | ||
733 | * since X_recv = 0 for the first feedback packet (cf. | ||
734 | * RFC 3448, 6.3) -- gerrit | ||
735 | */ | ||
736 | } | 726 | } |
737 | goto update_records; | 727 | goto update_records; |
738 | } | 728 | } |
739 | 729 | ||
740 | if (tfrc_rx_hist_duplicate(&hcrx->hist, skb)) | ||
741 | return; /* done receiving */ | ||
742 | |||
743 | if (is_data_packet) { | ||
744 | const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4; | ||
745 | /* | ||
746 | * Update moving-average of s and the sum of received payload bytes | ||
747 | */ | ||
748 | hcrx->s = tfrc_ewma(hcrx->s, payload, 9); | ||
749 | hcrx->bytes_recv += payload; | ||
750 | } | ||
751 | |||
752 | if (tfrc_rx_hist_loss_pending(&hcrx->hist)) | 730 | if (tfrc_rx_hist_loss_pending(&hcrx->hist)) |
753 | return; /* done receiving */ | 731 | return; /* done receiving */ |
754 | 732 | ||
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h index 1773a8dd36d8..0c4fadd85f94 100644 --- a/net/dccp/ccids/ccid3.h +++ b/net/dccp/ccids/ccid3.h | |||
@@ -124,25 +124,21 @@ enum ccid3_hc_rx_states { | |||
124 | * | 124 | * |
125 | * @last_counter - Tracks window counter (RFC 4342, 8.1) | 125 | * @last_counter - Tracks window counter (RFC 4342, 8.1) |
126 | * @state - Receiver state, one of %ccid3_hc_rx_states | 126 | * @state - Receiver state, one of %ccid3_hc_rx_states |
127 | * @bytes_recv - Total sum of DCCP payload bytes | ||
128 | * @x_recv - Receiver estimate of send rate (RFC 3448, sec. 4.3) | 127 | * @x_recv - Receiver estimate of send rate (RFC 3448, sec. 4.3) |
129 | * @rtt - Receiver estimate of RTT | 128 | * @rtt - Receiver estimate of RTT |
130 | * @tstamp_last_feedback - Time at which last feedback was sent | 129 | * @tstamp_last_feedback - Time at which last feedback was sent |
131 | * @hist - Packet history (loss detection + RTT sampling) | 130 | * @hist - Packet history (loss detection + RTT sampling) |
132 | * @li_hist - Loss Interval database | 131 | * @li_hist - Loss Interval database |
133 | * @s - Received packet size in bytes | ||
134 | * @p_inverse - Inverse of Loss Event Rate (RFC 4342, sec. 8.5) | 132 | * @p_inverse - Inverse of Loss Event Rate (RFC 4342, sec. 8.5) |
135 | */ | 133 | */ |
136 | struct ccid3_hc_rx_sock { | 134 | struct ccid3_hc_rx_sock { |
137 | u8 last_counter:4; | 135 | u8 last_counter:4; |
138 | enum ccid3_hc_rx_states state:8; | 136 | enum ccid3_hc_rx_states state:8; |
139 | u32 bytes_recv; | ||
140 | u32 x_recv; | 137 | u32 x_recv; |
141 | u32 rtt; | 138 | u32 rtt; |
142 | ktime_t tstamp_last_feedback; | 139 | ktime_t tstamp_last_feedback; |
143 | struct tfrc_rx_hist hist; | 140 | struct tfrc_rx_hist hist; |
144 | struct tfrc_loss_hist li_hist; | 141 | struct tfrc_loss_hist li_hist; |
145 | u16 s; | ||
146 | #define p_inverse li_hist.i_mean | 142 | #define p_inverse li_hist.i_mean |
147 | }; | 143 | }; |
148 | 144 | ||
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c index 8ea96903033d..ee34b4564242 100644 --- a/net/dccp/ccids/lib/packet_history.c +++ b/net/dccp/ccids/lib/packet_history.c | |||
@@ -352,6 +352,16 @@ int tfrc_rx_handle_loss(struct tfrc_rx_hist *h, | |||
352 | __three_after_loss(h); | 352 | __three_after_loss(h); |
353 | } | 353 | } |
354 | 354 | ||
355 | /* | ||
356 | * Update moving-average of `s' and the sum of received payload bytes. | ||
357 | */ | ||
358 | if (dccp_data_packet(skb)) { | ||
359 | const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4; | ||
360 | |||
361 | h->packet_size = tfrc_ewma(h->packet_size, payload, 9); | ||
362 | h->bytes_recvd += payload; | ||
363 | } | ||
364 | |||
355 | /* RFC 3448, 6.1: update I_0, whose growth implies p <= p_prev */ | 365 | /* RFC 3448, 6.1: update I_0, whose growth implies p <= p_prev */ |
356 | if (!is_new_loss) | 366 | if (!is_new_loss) |
357 | tfrc_lh_update_i_mean(lh, skb); | 367 | tfrc_lh_update_i_mean(lh, skb); |
diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h index e9d8097947d5..b7c87a1a2720 100644 --- a/net/dccp/ccids/lib/packet_history.h +++ b/net/dccp/ccids/lib/packet_history.h | |||
@@ -91,12 +91,16 @@ struct tfrc_rx_hist_entry { | |||
91 | * @loss_count: Number of entries in circular history | 91 | * @loss_count: Number of entries in circular history |
92 | * @loss_start: Movable index (for loss detection) | 92 | * @loss_start: Movable index (for loss detection) |
93 | * @rtt_sample_prev: Used during RTT sampling, points to candidate entry | 93 | * @rtt_sample_prev: Used during RTT sampling, points to candidate entry |
94 | * @packet_size: Packet size in bytes (as per RFC 3448, 3.1) | ||
95 | * @bytes_recvd: Number of bytes received since last sending feedback | ||
94 | */ | 96 | */ |
95 | struct tfrc_rx_hist { | 97 | struct tfrc_rx_hist { |
96 | struct tfrc_rx_hist_entry *ring[TFRC_NDUPACK + 1]; | 98 | struct tfrc_rx_hist_entry *ring[TFRC_NDUPACK + 1]; |
97 | u8 loss_count:2, | 99 | u8 loss_count:2, |
98 | loss_start:2; | 100 | loss_start:2; |
99 | #define rtt_sample_prev loss_start | 101 | #define rtt_sample_prev loss_start |
102 | u32 packet_size, | ||
103 | bytes_recvd; | ||
100 | }; | 104 | }; |
101 | 105 | ||
102 | /** | 106 | /** |
@@ -140,6 +144,18 @@ static inline bool tfrc_rx_hist_loss_pending(const struct tfrc_rx_hist *h) | |||
140 | return h->loss_count > 0; | 144 | return h->loss_count > 0; |
141 | } | 145 | } |
142 | 146 | ||
147 | /* | ||
148 | * Accessor functions to retrieve parameters sampled by the RX history | ||
149 | */ | ||
150 | static inline u32 tfrc_rx_hist_packet_size(const struct tfrc_rx_hist *h) | ||
151 | { | ||
152 | if (h->packet_size == 0) { | ||
153 | DCCP_WARN("No sample for s, using fallback\n"); | ||
154 | return TCP_MIN_RCVMSS; | ||
155 | } | ||
156 | return h->packet_size; | ||
157 | } | ||
158 | |||
143 | extern void tfrc_rx_hist_add_packet(struct tfrc_rx_hist *h, | 159 | extern void tfrc_rx_hist_add_packet(struct tfrc_rx_hist *h, |
144 | const struct sk_buff *skb, const u64 ndp); | 160 | const struct sk_buff *skb, const u64 ndp); |
145 | 161 | ||