aboutsummaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2011-12-08 21:46:45 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-09 13:46:15 -0500
commita73ed26bbae7327370c5bd298f07de78df9e3466 (patch)
tree3c7a04e638261cdd16c324ecd07e303e72fac3b9 /include/net
parent0221cd51543972782af558c527e4ac58b32049fa (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.h16
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
156static inline void red_set_parms(struct red_parms *p, 156static 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