[Codel] [PATCH] codel: Refine re-entering drop state to react sooner

Dave Taht dave.taht at gmail.com
Thu Aug 23 10:22:34 EDT 2012


re-re-reviewing this in the light of dawn...

On Thu, Aug 23, 2012 at 1:37 AM, Dave Täht <dave.taht at bufferbloat.net> wrote:
> From: Dave Taht <dave.taht at bufferbloat.net>
>
> This patch attempts to smooth out codel behavior in several ways.
>
> These first two are arguably bugs.
>
> 1) Newton's method doesn't run well in reverse, run it twice on a decline
> 2) Account for the idea of dropping out of drop state after a drop
> upon entering drop state.
>
> 3) the old "count - lastcount" method gyrates between a heavy dropping state
>    and nearly nothing when it should find an optimum. For example, if
>    the optimum count was 66, which was found by going up 6 from lastcount
>    of 60, the old result would be 6. In this version of the code, it
>    would be 63. Arguably this could be curved by the width of the
>    8*interval between entering drop states, so > interval * 4 could be
>    something like count = count - (3 * 4), or an ewma based on ldelay.
>
> 4) Note that in heavy dropping states, count now increases slower, as well,
> as it is moved outside of the while loop.
>
> Some of this is borrowed from ideas in the ns2 code.
> ---
>  include/net/codel.h |   44 ++++++++++++++++++++++++--------------------
>  1 file changed, 24 insertions(+), 20 deletions(-)
>
> diff --git a/include/net/codel.h b/include/net/codel.h
> index 389cf62..dbfccb7 100644
> --- a/include/net/codel.h
> +++ b/include/net/codel.h
> @@ -274,11 +274,11 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch,
>                          * that the next drop should happen now,
>                          * hence the while loop.
>                          */
> +                       vars->count++; /* don't care about possible wrap
> +                                       * since there is no more divide
> +                                       */
>                         while (vars->dropping &&
>                                codel_time_after_eq(now, vars->drop_next)) {
> -                               vars->count++; /* dont care of possible wrap
> -                                               * since there is no more divide
> -                                               */
>                                 codel_Newton_step(vars);

This is here because in an unfinished patch I'm incrementing count by more
if we are near queue size limits... and this approximation varies slightly...

>                                 if (params->ecn && INET_ECN_set_ce(skb)) {
>                                         stats->ecn_mark++;
> @@ -305,7 +305,7 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch,
>                         }
>                 }
>         } else if (drop) {
> -               u32 delta;
> +               s32 delta;
>
>                 if (params->ecn && INET_ECN_set_ce(skb)) {
>                         stats->ecn_mark++;
> @@ -317,28 +317,32 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch,
>                         drop = codel_should_drop(skb, sch, vars, params,
>                                                  stats, now);
>                 }
> -               vars->dropping = true;
> +               vars->dropping = drop;

bugfix was here

>                 /* if min went above target close to when we last went below it
>                  * assume that the drop rate that controlled the queue on the
>                  * last cycle is a good starting point to control it now.
>                  */
> -               delta = vars->count - vars->lastcount;
> -               if (delta > 1 &&
> -                   codel_time_before(now - vars->drop_next,
> -                                     16 * params->interval)) {
> -                       vars->count = delta;
> -                       /* we dont care if rec_inv_sqrt approximation
> -                        * is not very precise :
> -                        * Next Newton steps will correct it quadratically.
> +               if (drop) { /* we can exit dropping state above */

part 2 of that bugfix

> +                       delta = vars->count - 3;
> +                       if(codel_time_before(now - vars->drop_next,
> +                                     8 * params->interval)) {
> +                               vars->count = delta > 0 ? (u32) delta : 1;
> +                       /* we don't care if rec_inv_sqrt approximation
> +                        * in reverse is not very precise :
> +                        * 2 Newton steps will correct it quadratically.
>                          */
> -                       codel_Newton_step(vars);
> -               } else {
> -                       vars->count = 1;
> -                       vars->rec_inv_sqrt = ~0U >> REC_INV_SQRT_SHIFT;
> +                               codel_Newton_step(vars);
> +                               codel_Newton_step(vars);
> +                       } else {
> +                               vars->count = 1;
> +                               vars->rec_inv_sqrt = ~0U >> REC_INV_SQRT_SHIFT;
> +                               codel_Newton_step(vars);
> +                       }
> +                       vars->lastcount = vars->count;
> +                       vars->drop_next = codel_control_law(vars->drop_next,
> +                                                           params->interval,
> +                                                           vars->rec_inv_sqrt);

Actually this doesn't do what I want, I think. What I wanted was to
restart dropping at slightly less than the same rate over roughly the
same interval
since the last drop...

but we are if (8 * interval) here, I guess it makes more
sense to go with now... [me scratches head]

>                 }
> -               vars->lastcount = vars->count;
> -               vars->drop_next = codel_control_law(now, params->interval,
> -                                                   vars->rec_inv_sqrt);
>         }
>  end:
>         return skb;
> --
> 1.7.9.5
>
> _______________________________________________
> Codel mailing list
> Codel at lists.bufferbloat.net
> https://lists.bufferbloat.net/listinfo/codel



-- 
Dave Täht
http://www.bufferbloat.net/projects/cerowrt/wiki - "3.3.8-17 is out
with fq_codel!"



More information about the Codel mailing list