aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ccids/ccid3.c
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2006-11-28 16:22:33 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 00:30:58 -0500
commit78ad713da673a2977763521c347176137f3e493f (patch)
tree2ad817e9c90a46b8f0f2e41f60792fe5f00c865d /net/dccp/ccids/ccid3.c
parent2a1fda6f6c01d7ac195c040f14edcf9f64a5451e (diff)
[DCCP] ccid3: Track RX/TX packet size `s' using moving-average
Problem:
Diffstat (limited to 'net/dccp/ccids/ccid3.c')
-rw-r--r--net/dccp/ccids/ccid3.c60
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 */
166static 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
162static void ccid3_hc_tx_no_feedback_timer(unsigned long data) 181static 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
595static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) 620static 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
678static 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
661static void ccid3_hc_rx_send_feedback(struct sock *sk) 687static 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
1041static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) 1069static 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}