diff options
author | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2007-11-20 15:09:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:54:43 -0500 |
commit | c3ada46a009001e144b29736880962f24ee2afdf (patch) | |
tree | a475095e2ef5bff2f0d94a24ca94776578fe1c75 /net/dccp | |
parent | a5358fdc9c52e44d79dcd144375e089e166508d7 (diff) |
[CCID3]: Inline for moving average
The moving average computation occurs so frequently in the CCID 3 code that
it merits an inline function of its own. This is uses a suggestion by
Arnaldo as per http://www.mail-archive.com/dccp@vger.kernel.org/msg01662.html
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Signed-off-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/ccids/ccid3.c | 25 | ||||
-rw-r--r-- | net/dccp/ccids/lib/tfrc.h | 9 |
2 files changed, 14 insertions, 20 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 94a322863844..42893b1dfa09 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -192,7 +192,7 @@ static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len) | |||
192 | { | 192 | { |
193 | const u16 old_s = hctx->ccid3hctx_s; | 193 | const u16 old_s = hctx->ccid3hctx_s; |
194 | 194 | ||
195 | hctx->ccid3hctx_s = old_s == 0 ? len : (9 * old_s + len) / 10; | 195 | hctx->ccid3hctx_s = tfrc_ewma(hctx->ccid3hctx_s, len, 9); |
196 | 196 | ||
197 | if (hctx->ccid3hctx_s != old_s) | 197 | if (hctx->ccid3hctx_s != old_s) |
198 | ccid3_update_send_interval(hctx); | 198 | ccid3_update_send_interval(hctx); |
@@ -449,25 +449,15 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
449 | 449 | ||
450 | now = ktime_get_real(); | 450 | now = ktime_get_real(); |
451 | /* | 451 | /* |
452 | * Calculate new round trip sample as per [RFC 3448, 4.3] by | 452 | * Calculate new RTT sample and update moving average |
453 | * R_sample = (now - t_recvdata) - t_elapsed | ||
454 | */ | 453 | */ |
455 | r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, packet->dccphtx_tstamp)); | 454 | r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, packet->dccphtx_tstamp)); |
455 | hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9); | ||
456 | 456 | ||
457 | /* | ||
458 | * Update RTT estimate by | ||
459 | * If (No feedback recv) | ||
460 | * R = R_sample; | ||
461 | * Else | ||
462 | * R = q * R + (1 - q) * R_sample; | ||
463 | * | ||
464 | * q is a constant, RFC 3448 recomments 0.9 | ||
465 | */ | ||
466 | if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) { | 457 | if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) { |
467 | /* | 458 | /* |
468 | * Larger Initial Windows [RFC 4342, sec. 5] | 459 | * Larger Initial Windows [RFC 4342, sec. 5] |
469 | */ | 460 | */ |
470 | hctx->ccid3hctx_rtt = r_sample; | ||
471 | hctx->ccid3hctx_x = rfc3390_initial_rate(sk); | 461 | hctx->ccid3hctx_x = rfc3390_initial_rate(sk); |
472 | hctx->ccid3hctx_t_ld = now; | 462 | hctx->ccid3hctx_t_ld = now; |
473 | 463 | ||
@@ -481,8 +471,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
481 | 471 | ||
482 | ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK); | 472 | ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK); |
483 | } else { | 473 | } else { |
484 | hctx->ccid3hctx_rtt = (9 * hctx->ccid3hctx_rtt + | ||
485 | r_sample) / 10; | ||
486 | 474 | ||
487 | /* Update sending rate (step 4 of [RFC 3448, 4.3]) */ | 475 | /* Update sending rate (step 4 of [RFC 3448, 4.3]) */ |
488 | if (hctx->ccid3hctx_p > 0) | 476 | if (hctx->ccid3hctx_p > 0) |
@@ -700,11 +688,8 @@ static void ccid3_hc_rx_set_state(struct sock *sk, | |||
700 | 688 | ||
701 | static inline void ccid3_hc_rx_update_s(struct ccid3_hc_rx_sock *hcrx, int len) | 689 | static inline void ccid3_hc_rx_update_s(struct ccid3_hc_rx_sock *hcrx, int len) |
702 | { | 690 | { |
703 | if (unlikely(len == 0)) /* don't update on empty packets (e.g. ACKs) */ | 691 | if (likely(len > 0)) /* don't update on empty packets (e.g. ACKs) */ |
704 | ccid3_pr_debug("Packet payload length is 0 - not updating\n"); | 692 | hcrx->ccid3hcrx_s = tfrc_ewma(hcrx->ccid3hcrx_s, len, 9); |
705 | else | ||
706 | hcrx->ccid3hcrx_s = hcrx->ccid3hcrx_s == 0 ? len : | ||
707 | (9 * hcrx->ccid3hcrx_s + len) / 10; | ||
708 | } | 693 | } |
709 | 694 | ||
710 | static void ccid3_hc_rx_send_feedback(struct sock *sk) | 695 | static void ccid3_hc_rx_send_feedback(struct sock *sk) |
diff --git a/net/dccp/ccids/lib/tfrc.h b/net/dccp/ccids/lib/tfrc.h index faf5f7e219e3..5a0ba86df183 100644 --- a/net/dccp/ccids/lib/tfrc.h +++ b/net/dccp/ccids/lib/tfrc.h | |||
@@ -37,6 +37,15 @@ static inline u32 scaled_div32(u64 a, u32 b) | |||
37 | return result; | 37 | return result; |
38 | } | 38 | } |
39 | 39 | ||
40 | /** | ||
41 | * tfrc_ewma - Exponentially weighted moving average | ||
42 | * @weight: Weight to be used as damping factor, in units of 1/10 | ||
43 | */ | ||
44 | static inline u32 tfrc_ewma(const u32 avg, const u32 newval, const u8 weight) | ||
45 | { | ||
46 | return avg ? (weight * avg + (10 - weight) * newval) / 10 : newval; | ||
47 | } | ||
48 | |||
40 | extern u32 tfrc_calc_x(u16 s, u32 R, u32 p); | 49 | extern u32 tfrc_calc_x(u16 s, u32 R, u32 p); |
41 | extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue); | 50 | extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue); |
42 | 51 | ||