| 1 | From b8fc328668a74e1314a19266755a54abd875e5a6 Mon Sep 17 00:00:00 2001 |
| 2 | From: Eric Dumazet <edumazet@google.com> |
| 3 | Date: Sun, 29 Jul 2012 20:52:21 +0000 |
| 4 | Subject: [PATCH] codel: refine one condition to avoid a nul rec_inv_sqrt |
| 5 | |
| 6 | commit 2359a47671fc4fb0fe5e9945f76c2cb10792c0f8 upstream. |
| 7 | |
| 8 | One condition before codel_Newton_step() was not good if |
| 9 | we never left the dropping state for a flow. As a result |
| 10 | rec_inv_sqrt was 0, instead of the ~0 initial value. |
| 11 | |
| 12 | codel control law was then set to a very aggressive mode, dropping |
| 13 | many packets before reaching 'target' and recovering from this problem. |
| 14 | |
| 15 | To keep codel_vars_init() as efficient as possible, refine |
| 16 | the condition to make sure rec_inv_sqrt initial value is correct |
| 17 | |
| 18 | Many thanks to Anton Mich for discovering the issue and suggesting |
| 19 | a fix. |
| 20 | |
| 21 | Reported-by: Anton Mich <lp2s1h@gmail.com> |
| 22 | Signed-off-by: Eric Dumazet <edumazet@google.com> |
| 23 | Signed-off-by: David S. Miller <davem@davemloft.net> |
| 24 | --- |
| 25 | include/net/codel.h | 8 ++++++-- |
| 26 | 1 file changed, 6 insertions(+), 2 deletions(-) |
| 27 | |
| 28 | --- a/include/net/codel.h |
| 29 | +++ b/include/net/codel.h |
| 30 | @@ -305,6 +305,8 @@ static struct sk_buff *codel_dequeue(str |
| 31 | } |
| 32 | } |
| 33 | } else if (drop) { |
| 34 | + u32 delta; |
| 35 | + |
| 36 | if (params->ecn && INET_ECN_set_ce(skb)) { |
| 37 | stats->ecn_mark++; |
| 38 | } else { |
| 39 | @@ -320,9 +322,11 @@ static struct sk_buff *codel_dequeue(str |
| 40 | * assume that the drop rate that controlled the queue on the |
| 41 | * last cycle is a good starting point to control it now. |
| 42 | */ |
| 43 | - if (codel_time_before(now - vars->drop_next, |
| 44 | + delta = vars->count - vars->lastcount; |
| 45 | + if (delta > 1 && |
| 46 | + codel_time_before(now - vars->drop_next, |
| 47 | 16 * params->interval)) { |
| 48 | - vars->count = (vars->count - vars->lastcount) | 1; |
| 49 | + vars->count = delta; |
| 50 | /* we dont care if rec_inv_sqrt approximation |
| 51 | * is not very precise : |
| 52 | * Next Newton steps will correct it quadratically. |
| 53 | |