diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-12-08 21:46:45 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-09 13:46:15 -0500 |
commit | a73ed26bbae7327370c5bd298f07de78df9e3466 (patch) | |
tree | 3c7a04e638261cdd16c324ecd07e303e72fac3b9 /include/net | |
parent | 0221cd51543972782af558c527e4ac58b32049fa (diff) |
sch_red: generalize accurate MAX_P support to RED/GRED/CHOKE
Now RED uses a Q0.32 number to store max_p (max probability), allow
RED/GRED/CHOKE to use/report full resolution at config/dump time.
Old tc binaries are non aware of new attributes, and still set/get Plog.
New tc binary set/get both Plog and max_p for backward compatibility,
they display "probability value" if they get max_p from new kernels.
# tc -d qdisc show dev ...
...
qdisc red 10: parent 1:1 limit 360Kb min 30Kb max 90Kb ecn ewma 5
probability 0.09 Scell_log 15
Make sure we avoid potential divides by 0 in reciprocal_value(), if
(max_th - min_th) is big.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/red.h | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/include/net/red.h b/include/net/red.h index 24606b22d01e..ef715a16cce4 100644 --- a/include/net/red.h +++ b/include/net/red.h | |||
@@ -155,9 +155,10 @@ static inline u32 red_maxp(u8 Plog) | |||
155 | 155 | ||
156 | static inline void red_set_parms(struct red_parms *p, | 156 | static inline void red_set_parms(struct red_parms *p, |
157 | u32 qth_min, u32 qth_max, u8 Wlog, u8 Plog, | 157 | u32 qth_min, u32 qth_max, u8 Wlog, u8 Plog, |
158 | u8 Scell_log, u8 *stab) | 158 | u8 Scell_log, u8 *stab, u32 max_P) |
159 | { | 159 | { |
160 | int delta = qth_max - qth_min; | 160 | int delta = qth_max - qth_min; |
161 | u32 max_p_delta; | ||
161 | 162 | ||
162 | /* Reset average queue length, the value is strictly bound | 163 | /* Reset average queue length, the value is strictly bound |
163 | * to the parameters below, reseting hurts a bit but leaving | 164 | * to the parameters below, reseting hurts a bit but leaving |
@@ -173,10 +174,14 @@ static inline void red_set_parms(struct red_parms *p, | |||
173 | if (delta < 0) | 174 | if (delta < 0) |
174 | delta = 1; | 175 | delta = 1; |
175 | p->qth_delta = delta; | 176 | p->qth_delta = delta; |
176 | p->max_P = red_maxp(Plog); | 177 | if (!max_P) { |
177 | p->max_P *= delta; /* max_P = (qth_max-qth_min)/2^Plog */ | 178 | max_P = red_maxp(Plog); |
178 | 179 | max_P *= delta; /* max_P = (qth_max - qth_min)/2^Plog */ | |
179 | p->max_P_reciprocal = reciprocal_value(p->max_P / delta); | 180 | } |
181 | p->max_P = max_P; | ||
182 | max_p_delta = max_P / delta; | ||
183 | max_p_delta = max(max_p_delta, 1U); | ||
184 | p->max_P_reciprocal = reciprocal_value(max_p_delta); | ||
180 | 185 | ||
181 | /* RED Adaptative target : | 186 | /* RED Adaptative target : |
182 | * [min_th + 0.4*(min_th - max_th), | 187 | * [min_th + 0.4*(min_th - max_th), |
@@ -380,6 +385,7 @@ static inline void red_adaptative_algo(struct red_parms *p) | |||
380 | p->max_P = (p->max_P/10)*9; /* maxp = maxp * Beta */ | 385 | p->max_P = (p->max_P/10)*9; /* maxp = maxp * Beta */ |
381 | 386 | ||
382 | max_p_delta = DIV_ROUND_CLOSEST(p->max_P, p->qth_delta); | 387 | max_p_delta = DIV_ROUND_CLOSEST(p->max_P, p->qth_delta); |
388 | max_p_delta = max(max_p_delta, 1U); | ||
383 | p->max_P_reciprocal = reciprocal_value(max_p_delta); | 389 | p->max_P_reciprocal = reciprocal_value(max_p_delta); |
384 | } | 390 | } |
385 | #endif | 391 | #endif |