Problem:
--------
Currently packet transmissions are not scheduled according to [RFC 3448, 4.6]
and
will, in the worst case, be sent later than necessary. If scheduled
transmission
requires using a delay, the current delay value is also larger as necessary.
Solution:
---------
This patch fixes time and delay calculation for scheduling CCID 3 packets.
D e t a i l e d D e r i v a t i o n
=====================================
Background:
-----------
[RFC 3448, 4.6] specifies the scheduling of packet transmissions with regard to
scheduling granularity. The calculated sending time is called `nominal' sending
time t_nom. The initial sending time is called t_0. The first sending time is
called
t_1 = t0 + t_ipi. From then on, successive sending times are calculated as
t_nom = t_(i+1) = t_i + t_ipi
This is illustrated by the ASCII-Art below:
|<-------------------- t_ipi ------------------->|
+------------------------------------------------+-----------------------
| | |
| | |
+------------------------------------------------+-----------------------
| ^ |<------- t_delta ------>|
| | | |
t_i t_now t_nom - t_delta t_nom = t_(i+1)
|<----- t_ipi - (t_now - t_i) --->|
Due to scheduling granularity, t_nom is not necessarily exactly the same as the
actual sending time, hence [RFC 3448, 4.6] introduced the following test:
t_delta = min(t_ipi/2, t_gran/2); /* t_gran: scheduling granularity */
if (t_now > t_nom - t_delta)
// send the packet now
else
// send the packet in t_ipi - (t_now - t_i) microseconds
In the above illustration, t_now was too early for sending (`else' case).
Current state:
--------------
Currently the code determines nominal send times using the following
pseudo-code:
delay_in_msec = -1/1000 * (t_now - t_nom - t_delta)
= 1/1000 * (t_nom + t_delta - t_now)
if (delay_in_msec > 0) /* equivalent to t_now < t_nom + t_delta
*/
return delay_in_msec; /* i.e. reschedule in (t_nom -(t_now -
t_delta))/1000 */
else /* whenever t_now >= t_nom + t_delta
*/
/* send packet now */
This means that currently
* the packet is sent now whenever t_now >= t_nom + t_delta
instead of t_now > t_nom - t_delta
==> this incurs a performance degradation, since 2*t_delta is spent
unnecessarily
* the delay causes the packet to be rescheduled at the following point of
time:
t_now + (t_nom + t_delta - t_now) = t_nom + t_delta
Hence again t_delta time units are not used.
Solution:
---------
The condition `if (t_now > t_nom - t_delta)' from [RFC 3448, 4.6] is
equivalent with
the condition `if (t_nom - t_now < t_delta)' and the delay simplifies (cf.
above figure):
t_ipi - (t_now - t_i) = t_i + t_ipi - t_now
= t_nom - t_now
Thus we can twice use `t_nom - t_now', which is what the patch does.
Signed-off-by: Gerrit Renker <[EMAIL PROTECTED]>
Signed-off-by: Ian McDonald <[EMAIL PROTECTED]>
Signed-off-by: Arnaldo Carvalho de Melo <[EMAIL PROTECTED]>
---
net/dccp/ccids/ccid3.c | 18 +++++++++++++-----
1 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index df88c54..fb1a5e8 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -304,11 +304,19 @@ static int ccid3_hc_tx_send_packet(struc
break;
case TFRC_SSTATE_NO_FBACK:
case TFRC_SSTATE_FBACK:
- delay = (timeval_delta(&now, &hctx->ccid3hctx_t_nom) -
- hctx->ccid3hctx_delta);
- delay /= -1000;
- /* divide by -1000 is to convert to ms and get sign right */
- rc = delay > 0 ? delay : 0;
+ delay = timeval_delta(&hctx->ccid3hctx_t_nom, &now);
+ /*
+ * Scheduling of packet transmissions [RFC 3448, 4.6]
+ *
+ * if (t_now > t_nom - delta)
+ * // send the packet now
+ * else
+ * // send the packet in (t_nom - t_now) milliseconds.
+ */
+ if (delay < hctx->ccid3hctx_delta)
+ rc = 0;
+ else
+ rc = delay/1000L;
break;
case TFRC_SSTATE_TERM:
DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk);
--
1.4.2.1.g3d5c
-
To unsubscribe from this list: send the line "unsubscribe dccp" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html