[CCID3]: Nofeedback timer according to rfc3448bis
This implements the changes to the nofeedback timer handling suggested in draft rfc3448bis00, section 4.4. In particular, these changes mean: * better handling of the lossless case (p == 0) * the timestamp for computing t_ld becomes obsolete * much more recent document (RFC 3448 is almost 5 years old) * concepts in rfc3448bis arose from a real, working implementation (cf. sec. 12) 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>
This commit is contained in:
committed by
David S. Miller
parent
d8d1252f74
commit
52515e77a7
@@ -131,7 +131,6 @@ static u32 ccid3_hc_tx_idle_rtt(struct ccid3_hc_tx_sock *hctx, ktime_t now)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp)
|
static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp)
|
||||||
|
|
||||||
{
|
{
|
||||||
struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
|
struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
|
||||||
__u64 min_rate = 2 * hctx->ccid3hctx_x_recv;
|
__u64 min_rate = 2 * hctx->ccid3hctx_x_recv;
|
||||||
@@ -230,27 +229,27 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
|
|||||||
ccid3_pr_debug("%s(%p, state=%s) - entry \n", dccp_role(sk), sk,
|
ccid3_pr_debug("%s(%p, state=%s) - entry \n", dccp_role(sk), sk,
|
||||||
ccid3_tx_state_name(hctx->ccid3hctx_state));
|
ccid3_tx_state_name(hctx->ccid3hctx_state));
|
||||||
|
|
||||||
switch (hctx->ccid3hctx_state) {
|
if (hctx->ccid3hctx_state == TFRC_SSTATE_FBACK)
|
||||||
case TFRC_SSTATE_NO_FBACK:
|
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
|
||||||
/* RFC 3448, 4.4: Halve send rate directly */
|
else if (hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4
|
||||||
|
*/
|
||||||
|
if (hctx->ccid3hctx_t_rto == 0 || /* no feedback received yet */
|
||||||
|
hctx->ccid3hctx_p == 0) {
|
||||||
|
|
||||||
|
/* halve send rate directly */
|
||||||
hctx->ccid3hctx_x = max(hctx->ccid3hctx_x / 2,
|
hctx->ccid3hctx_x = max(hctx->ccid3hctx_x / 2,
|
||||||
(((__u64)hctx->ccid3hctx_s) << 6) /
|
(((__u64)hctx->ccid3hctx_s) << 6) /
|
||||||
TFRC_T_MBI);
|
TFRC_T_MBI);
|
||||||
|
|
||||||
ccid3_pr_debug("%s(%p, state=%s), updated tx rate to %u "
|
|
||||||
"bytes/s\n", dccp_role(sk), sk,
|
|
||||||
ccid3_tx_state_name(hctx->ccid3hctx_state),
|
|
||||||
(unsigned)(hctx->ccid3hctx_x >> 6));
|
|
||||||
/* The value of R is still undefined and so we can not recompute
|
|
||||||
* the timeout value. Keep initial value as per [RFC 4342, 5]. */
|
|
||||||
t_nfb = TFRC_INITIAL_TIMEOUT;
|
|
||||||
ccid3_update_send_interval(hctx);
|
ccid3_update_send_interval(hctx);
|
||||||
break;
|
} else {
|
||||||
case TFRC_SSTATE_FBACK:
|
|
||||||
/*
|
/*
|
||||||
* Modify the cached value of X_recv [RFC 3448, 4.4]
|
* Modify the cached value of X_recv
|
||||||
*
|
*
|
||||||
* If (p == 0 || X_calc > 2 * X_recv)
|
* If (X_calc > 2 * X_recv)
|
||||||
* X_recv = max(X_recv / 2, s / (2 * t_mbi));
|
* X_recv = max(X_recv / 2, s / (2 * t_mbi));
|
||||||
* Else
|
* Else
|
||||||
* X_recv = X_calc / 4;
|
* X_recv = X_calc / 4;
|
||||||
@@ -259,32 +258,28 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
|
|||||||
*/
|
*/
|
||||||
BUG_ON(hctx->ccid3hctx_p && !hctx->ccid3hctx_x_calc);
|
BUG_ON(hctx->ccid3hctx_p && !hctx->ccid3hctx_x_calc);
|
||||||
|
|
||||||
if (hctx->ccid3hctx_p == 0 ||
|
if (hctx->ccid3hctx_x_calc > (hctx->ccid3hctx_x_recv >> 5))
|
||||||
(hctx->ccid3hctx_x_calc > (hctx->ccid3hctx_x_recv >> 5))) {
|
|
||||||
|
|
||||||
hctx->ccid3hctx_x_recv =
|
hctx->ccid3hctx_x_recv =
|
||||||
max(hctx->ccid3hctx_x_recv / 2,
|
max(hctx->ccid3hctx_x_recv / 2,
|
||||||
(((__u64)hctx->ccid3hctx_s) << 6) /
|
(((__u64)hctx->ccid3hctx_s) << 6) /
|
||||||
(2 * TFRC_T_MBI));
|
(2 * TFRC_T_MBI));
|
||||||
} else {
|
else {
|
||||||
hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc;
|
hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc;
|
||||||
hctx->ccid3hctx_x_recv <<= 4;
|
hctx->ccid3hctx_x_recv <<= 4;
|
||||||
}
|
}
|
||||||
/* Now recalculate X [RFC 3448, 4.3, step (4)] */
|
|
||||||
ccid3_hc_tx_update_x(sk, NULL);
|
ccid3_hc_tx_update_x(sk, NULL);
|
||||||
|
}
|
||||||
|
ccid3_pr_debug("Reduced X to %llu/64 bytes/sec\n",
|
||||||
|
(unsigned long long)hctx->ccid3hctx_x);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Schedule no feedback timer to expire in
|
* Set new timeout for the nofeedback timer.
|
||||||
* max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi)
|
|
||||||
* See comments in packet_recv() regarding the value of t_RTO.
|
* See comments in packet_recv() regarding the value of t_RTO.
|
||||||
*/
|
*/
|
||||||
|
if (unlikely(hctx->ccid3hctx_t_rto == 0)) /* no feedback yet */
|
||||||
|
t_nfb = TFRC_INITIAL_TIMEOUT;
|
||||||
|
else
|
||||||
t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
|
t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
|
||||||
break;
|
|
||||||
case TFRC_SSTATE_NO_SENT:
|
|
||||||
DCCP_BUG("%s(%p) - Illegal state NO_SENT", dccp_role(sk), sk);
|
|
||||||
/* fall through */
|
|
||||||
case TFRC_SSTATE_TERM:
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
restart_timer:
|
restart_timer:
|
||||||
sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
|
sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
|
||||||
|
Reference in New Issue
Block a user