diff options
author | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2006-11-28 16:22:33 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:30:58 -0500 |
commit | 78ad713da673a2977763521c347176137f3e493f (patch) | |
tree | 2ad817e9c90a46b8f0f2e41f60792fe5f00c865d | |
parent | 2a1fda6f6c01d7ac195c040f14edcf9f64a5451e (diff) |
[DCCP] ccid3: Track RX/TX packet size `s' using moving-average
Problem:
-rw-r--r-- | net/dccp/ccids/ccid3.c | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 577fd0ef84e5..05513f3df652 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -159,6 +159,25 @@ static void ccid3_hc_tx_update_x(struct sock *sk) | |||
159 | ccid3_update_send_time(hctx); | 159 | ccid3_update_send_time(hctx); |
160 | } | 160 | } |
161 | 161 | ||
162 | /* | ||
163 | * Track the mean packet size `s' (cf. RFC 4342, 5.3 and RFC 3448, 4.1) | ||
164 | * @len: DCCP packet payload size in bytes | ||
165 | */ | ||
166 | static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len) | ||
167 | { | ||
168 | if (unlikely(len == 0)) | ||
169 | ccid3_pr_debug("Packet payload length is 0 - not updating\n"); | ||
170 | else | ||
171 | hctx->ccid3hctx_s = hctx->ccid3hctx_s == 0 ? len : | ||
172 | (9 * hctx->ccid3hctx_s + len) / 10; | ||
173 | /* | ||
174 | * Note: We could do a potential optimisation here - when `s' changes, | ||
175 | * recalculate sending rate and consequently t_ipi, t_delta, and | ||
176 | * t_now. This is however non-standard, and the benefits are not | ||
177 | * clear, so it is currently left out. | ||
178 | */ | ||
179 | } | ||
180 | |||
162 | static void ccid3_hc_tx_no_feedback_timer(unsigned long data) | 181 | static void ccid3_hc_tx_no_feedback_timer(unsigned long data) |
163 | { | 182 | { |
164 | struct sock *sk = (struct sock *)data; | 183 | struct sock *sk = (struct sock *)data; |
@@ -299,6 +318,10 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, | |||
299 | hctx->ccid3hctx_t_last_win_count = now; | 318 | hctx->ccid3hctx_t_last_win_count = now; |
300 | ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); | 319 | ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); |
301 | 320 | ||
321 | /* Set initial sending rate to 1 packet per second */ | ||
322 | ccid3_hc_tx_update_s(hctx, len); | ||
323 | hctx->ccid3hctx_x = hctx->ccid3hctx_s; | ||
324 | |||
302 | /* First timeout, according to [RFC 3448, 4.2], is 1 second */ | 325 | /* First timeout, according to [RFC 3448, 4.2], is 1 second */ |
303 | hctx->ccid3hctx_t_ipi = USEC_PER_SEC; | 326 | hctx->ccid3hctx_t_ipi = USEC_PER_SEC; |
304 | /* Initial delta: minimum of 0.5 sec and t_gran/2 */ | 327 | /* Initial delta: minimum of 0.5 sec and t_gran/2 */ |
@@ -350,6 +373,8 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len) | |||
350 | unsigned long quarter_rtt; | 373 | unsigned long quarter_rtt; |
351 | struct dccp_tx_hist_entry *packet; | 374 | struct dccp_tx_hist_entry *packet; |
352 | 375 | ||
376 | ccid3_hc_tx_update_s(hctx, len); | ||
377 | |||
353 | packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist); | 378 | packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist); |
354 | if (unlikely(packet == NULL)) { | 379 | if (unlikely(packet == NULL)) { |
355 | DCCP_WARN("packet doesn't exist in history!\n"); | 380 | DCCP_WARN("packet doesn't exist in history!\n"); |
@@ -594,17 +619,9 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, | |||
594 | 619 | ||
595 | static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) | 620 | static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) |
596 | { | 621 | { |
597 | struct dccp_sock *dp = dccp_sk(sk); | ||
598 | struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid); | 622 | struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid); |
599 | 623 | ||
600 | if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && | 624 | hctx->ccid3hctx_s = 0; |
601 | dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) | ||
602 | hctx->ccid3hctx_s = dp->dccps_packet_size; | ||
603 | else | ||
604 | hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE; | ||
605 | |||
606 | /* Set transmission rate to 1 packet per second */ | ||
607 | hctx->ccid3hctx_x = hctx->ccid3hctx_s; | ||
608 | hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; | 625 | hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; |
609 | INIT_LIST_HEAD(&hctx->ccid3hctx_hist); | 626 | INIT_LIST_HEAD(&hctx->ccid3hctx_hist); |
610 | 627 | ||
@@ -658,6 +675,15 @@ static void ccid3_hc_rx_set_state(struct sock *sk, | |||
658 | hcrx->ccid3hcrx_state = state; | 675 | hcrx->ccid3hcrx_state = state; |
659 | } | 676 | } |
660 | 677 | ||
678 | static inline void ccid3_hc_rx_update_s(struct ccid3_hc_rx_sock *hcrx, int len) | ||
679 | { | ||
680 | if (unlikely(len == 0)) /* don't update on empty packets (e.g. ACKs) */ | ||
681 | ccid3_pr_debug("Packet payload length is 0 - not updating\n"); | ||
682 | else | ||
683 | hcrx->ccid3hcrx_s = hcrx->ccid3hcrx_s == 0 ? len : | ||
684 | (9 * hcrx->ccid3hcrx_s + len) / 10; | ||
685 | } | ||
686 | |||
661 | static void ccid3_hc_rx_send_feedback(struct sock *sk) | 687 | static void ccid3_hc_rx_send_feedback(struct sock *sk) |
662 | { | 688 | { |
663 | struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); | 689 | struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); |
@@ -934,7 +960,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
934 | struct dccp_rx_hist_entry *packet; | 960 | struct dccp_rx_hist_entry *packet; |
935 | struct timeval now; | 961 | struct timeval now; |
936 | u32 p_prev, rtt_prev, r_sample, t_elapsed; | 962 | u32 p_prev, rtt_prev, r_sample, t_elapsed; |
937 | int loss; | 963 | int loss, payload_size; |
938 | 964 | ||
939 | BUG_ON(hcrx == NULL); | 965 | BUG_ON(hcrx == NULL); |
940 | 966 | ||
@@ -989,6 +1015,9 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
989 | if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK) | 1015 | if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK) |
990 | return; | 1016 | return; |
991 | 1017 | ||
1018 | payload_size = skb->len - dccp_hdr(skb)->dccph_doff * 4; | ||
1019 | ccid3_hc_rx_update_s(hcrx, payload_size); | ||
1020 | |||
992 | switch (hcrx->ccid3hcrx_state) { | 1021 | switch (hcrx->ccid3hcrx_state) { |
993 | case TFRC_RSTATE_NO_DATA: | 1022 | case TFRC_RSTATE_NO_DATA: |
994 | ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial " | 1023 | ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial " |
@@ -999,8 +1028,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
999 | ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA); | 1028 | ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA); |
1000 | return; | 1029 | return; |
1001 | case TFRC_RSTATE_DATA: | 1030 | case TFRC_RSTATE_DATA: |
1002 | hcrx->ccid3hcrx_bytes_recv += skb->len - | 1031 | hcrx->ccid3hcrx_bytes_recv += payload_size; |
1003 | dccp_hdr(skb)->dccph_doff * 4; | ||
1004 | if (loss) | 1032 | if (loss) |
1005 | break; | 1033 | break; |
1006 | 1034 | ||
@@ -1040,22 +1068,16 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
1040 | 1068 | ||
1041 | static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) | 1069 | static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) |
1042 | { | 1070 | { |
1043 | struct dccp_sock *dp = dccp_sk(sk); | ||
1044 | struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid); | 1071 | struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid); |
1045 | 1072 | ||
1046 | ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); | 1073 | ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); |
1047 | 1074 | ||
1048 | if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && | ||
1049 | dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) | ||
1050 | hcrx->ccid3hcrx_s = dp->dccps_packet_size; | ||
1051 | else | ||
1052 | hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE; | ||
1053 | |||
1054 | hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA; | 1075 | hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA; |
1055 | INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist); | 1076 | INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist); |
1056 | INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist); | 1077 | INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist); |
1057 | dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack); | 1078 | dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack); |
1058 | hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack; | 1079 | hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack; |
1080 | hcrx->ccid3hcrx_s = 0; | ||
1059 | hcrx->ccid3hcrx_rtt = 5000; /* XXX 5ms for now... */ | 1081 | hcrx->ccid3hcrx_rtt = 5000; /* XXX 5ms for now... */ |
1060 | return 0; | 1082 | return 0; |
1061 | } | 1083 | } |