[PATCH 3/8] [DCCP] ccid3: Fix calculation of t_ipi time of scheduled transmission

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <gerrit@xxxxxxxxxxxxxx>
Signed-off-by: Ian McDonald <ian.mcdonald@xxxxxxxxxxx>
Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel]     [IETF DCCP]     [Linux Networking]     [Git]     [Security]     [Linux Assembly]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux