Re: [PATCH 3/6]: Fix calculation of t_ipi time of scheduled transmission

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

 



Quoting Ian McDonald:
|  I'll have to have a think about this one some more as I spent a lot of
|  time fixing these timing and I distinctly remember getting this one
|  right! 
Please relax: It is not my intention to embark on a game of "who is right here". I think
you have done a good job getting this code so far as it is, given the many and in parts
confusing documents that have to be read (for comparison: UDP, RFC 768, needs only 3 pages). 
My intention is in making sure it meets the specifications and contribute where I can to fix things.

Regarding the patch: I have satisfied myself that what I am doing is correct, 
                     I have added detailed explanations/illustrations so that others can validate
                     that it is indeed correct, and point out if I should have made an error.

|  The timing is altered all over the code and it can't be fixed 
|  in one place in isolation (unless the whole code is simplified).
If you are saying that the other code depends on calculating t_ipi in this non-standard fashion,
then it is high time that the other code also gets fixed.
However, I don't believe so since t_ipi and t_delta are recalculated in only two places:
  * in ccid3_hc_tx_packet_sent, state TFRC_SSTATE_FBACK:
	 
		timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);
		ccid3_calc_new_t_ipi(hctx);
		ccid3_calc_new_delta(hctx);
		timeval_add_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);

  * in ccid3_hc_tx_packet_recv, after updating X_calc:
				
		/* Update sending rate */
		ccid3_hc_tx_update_x(sk);

		/* Update next send time */
		timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);
		ccid3_calc_new_t_ipi(hctx);
		timeval_add_usecs(&hctx->ccid3hctx_t_nom,
				  hctx->ccid3hctx_t_ipi);
		ccid3_calc_new_delta(hctx);

  ==> Since these bits are so similar, I would actually suggest to accommodate them in 
      one function, since:
		--t_ipi changes only if one of `s' or X_calc changes
		--if `s' / X_calc remain unchanged after feedback, t_ipi remains as before
		--t_delta depends on t_ipi
		--the calculation of t_nom depends on t_ipi (as in the above snippets)

Conclusion:
-----------
  I remain unconvinced that the code below violates anything: it is a fix. If there are bits
  of the code you think depend on this then these too should be fixed.t_ipi by definition only
  depends on X_calc, s, and the initial settings from RFC 3448, 4.6; it should not have or satisfy
  other dependencies. If this is the case, please point out these things or submit a patch.
  I am willing to help fixing these issues and open to argumentation,  but I am not willing to
  retract the patch unless there are sound arguments against it.

Gerrit
|  
|  I'll study this some more when I can...
|  
|  On 11/22/06, Gerrit Renker <gerrit@xxxxxxxxxxxxxx> wrote:
|  > [CCID 3]: Fix calculation of t_ipi time of scheduled transmission
|  >
|  > 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.
|  >
|  >
|  > Signed-off-by: Gerrit Renker <gerrit@xxxxxxxxxxxxxx>
|  >
|  >
|  >
|  >     D e t a i l e d   D e r i v a t i o n   [not meant as commit message]
|  >     =====================================================================
|  >
|  > 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.
|  >
|  > ---
|  >  net/dccp/ccids/ccid3.c |   18 +++++++++++++-----
|  >  1 file changed, 13 insertions(+), 5 deletions(-)
|  >
|  > --- a/net/dccp/ccids/ccid3.c
|  > +++ b/net/dccp/ccids/ccid3.c
|  > @@ -303,11 +303,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);
|  > -
|  > 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
|  >
|  
|  
-
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