diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/sched/sch_gred.c | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index 38dab959feed..646dbdc4ef29 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c | |||
@@ -176,20 +176,24 @@ gred_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
176 | dp = tc_index_to_dp(skb); | 176 | dp = tc_index_to_dp(skb); |
177 | 177 | ||
178 | if (dp >= t->DPs || (q = t->tab[dp]) == NULL) { | 178 | if (dp >= t->DPs || (q = t->tab[dp]) == NULL) { |
179 | printk("GRED: setting to default (%d)\n ",t->def); | 179 | dp = t->def; |
180 | if (!(q=t->tab[t->def])) { | 180 | |
181 | DPRINTK("GRED: setting to default FAILED! dropping!! " | 181 | if ((q = t->tab[dp]) == NULL) { |
182 | "(%d)\n ", t->def); | 182 | /* Pass through packets not assigned to a DP |
183 | goto drop; | 183 | * if no default DP has been configured. This |
184 | * allows for DP flows to be left untouched. | ||
185 | */ | ||
186 | if (skb_queue_len(&sch->q) < sch->dev->tx_queue_len) | ||
187 | return qdisc_enqueue_tail(skb, sch); | ||
188 | else | ||
189 | goto drop; | ||
184 | } | 190 | } |
191 | |||
185 | /* fix tc_index? --could be controvesial but needed for | 192 | /* fix tc_index? --could be controvesial but needed for |
186 | requeueing */ | 193 | requeueing */ |
187 | skb->tc_index=(skb->tc_index & ~GRED_VQ_MASK) | t->def; | 194 | skb->tc_index = (skb->tc_index & ~GRED_VQ_MASK) | dp; |
188 | } | 195 | } |
189 | 196 | ||
190 | D2PRINTK("gred_enqueue virtualQ 0x%x classid %x backlog %d " | ||
191 | "general backlog %d\n",skb->tc_index&0xf,sch->handle,q->backlog, | ||
192 | sch->qstats.backlog); | ||
193 | /* sum up all the qaves of prios <= to ours to get the new qave*/ | 197 | /* sum up all the qaves of prios <= to ours to get the new qave*/ |
194 | if (!gred_wred_mode(t) && gred_rio_mode(t)) { | 198 | if (!gred_wred_mode(t) && gred_rio_mode(t)) { |
195 | for (i=0;i<t->DPs;i++) { | 199 | for (i=0;i<t->DPs;i++) { |
@@ -254,13 +258,20 @@ static int | |||
254 | gred_requeue(struct sk_buff *skb, struct Qdisc* sch) | 258 | gred_requeue(struct sk_buff *skb, struct Qdisc* sch) |
255 | { | 259 | { |
256 | struct gred_sched *t = qdisc_priv(sch); | 260 | struct gred_sched *t = qdisc_priv(sch); |
257 | struct gred_sched_data *q = t->tab[tc_index_to_dp(skb)]; | 261 | struct gred_sched_data *q; |
258 | /* error checking here -- probably unnecessary */ | 262 | u16 dp = tc_index_to_dp(skb); |
259 | 263 | ||
260 | if (red_is_idling(&q->parms)) | 264 | if (dp >= t->DPs || (q = t->tab[dp]) == NULL) { |
261 | red_end_of_idle_period(&q->parms); | 265 | if (net_ratelimit()) |
266 | printk(KERN_WARNING "GRED: Unable to relocate VQ 0x%x " | ||
267 | "for requeue, screwing up backlog.\n", | ||
268 | tc_index_to_dp(skb)); | ||
269 | } else { | ||
270 | if (red_is_idling(&q->parms)) | ||
271 | red_end_of_idle_period(&q->parms); | ||
272 | q->backlog += skb->len; | ||
273 | } | ||
262 | 274 | ||
263 | q->backlog += skb->len; | ||
264 | return qdisc_requeue(skb, sch); | 275 | return qdisc_requeue(skb, sch); |
265 | } | 276 | } |
266 | 277 | ||
@@ -274,15 +285,20 @@ gred_dequeue(struct Qdisc* sch) | |||
274 | skb = qdisc_dequeue_head(sch); | 285 | skb = qdisc_dequeue_head(sch); |
275 | 286 | ||
276 | if (skb) { | 287 | if (skb) { |
277 | q = t->tab[tc_index_to_dp(skb)]; | 288 | u16 dp = tc_index_to_dp(skb); |
278 | if (q) { | 289 | |
290 | if (dp >= t->DPs || (q = t->tab[dp]) == NULL) { | ||
291 | if (net_ratelimit()) | ||
292 | printk(KERN_WARNING "GRED: Unable to relocate " | ||
293 | "VQ 0x%x after dequeue, screwing up " | ||
294 | "backlog.\n", tc_index_to_dp(skb)); | ||
295 | } else { | ||
279 | q->backlog -= skb->len; | 296 | q->backlog -= skb->len; |
297 | |||
280 | if (!q->backlog && !gred_wred_mode(t)) | 298 | if (!q->backlog && !gred_wred_mode(t)) |
281 | red_start_of_idle_period(&q->parms); | 299 | red_start_of_idle_period(&q->parms); |
282 | } else { | ||
283 | D2PRINTK("gred_dequeue: skb has bad tcindex %x\n", | ||
284 | tc_index_to_dp(skb)); | ||
285 | } | 300 | } |
301 | |||
286 | return skb; | 302 | return skb; |
287 | } | 303 | } |
288 | 304 | ||
@@ -308,15 +324,19 @@ static unsigned int gred_drop(struct Qdisc* sch) | |||
308 | skb = qdisc_dequeue_tail(sch); | 324 | skb = qdisc_dequeue_tail(sch); |
309 | if (skb) { | 325 | if (skb) { |
310 | unsigned int len = skb->len; | 326 | unsigned int len = skb->len; |
311 | q = t->tab[tc_index_to_dp(skb)]; | 327 | u16 dp = tc_index_to_dp(skb); |
312 | if (q) { | 328 | |
329 | if (dp >= t->DPs || (q = t->tab[dp]) == NULL) { | ||
330 | if (net_ratelimit()) | ||
331 | printk(KERN_WARNING "GRED: Unable to relocate " | ||
332 | "VQ 0x%x while dropping, screwing up " | ||
333 | "backlog.\n", tc_index_to_dp(skb)); | ||
334 | } else { | ||
313 | q->backlog -= len; | 335 | q->backlog -= len; |
314 | q->stats.other++; | 336 | q->stats.other++; |
337 | |||
315 | if (!q->backlog && !gred_wred_mode(t)) | 338 | if (!q->backlog && !gred_wred_mode(t)) |
316 | red_start_of_idle_period(&q->parms); | 339 | red_start_of_idle_period(&q->parms); |
317 | } else { | ||
318 | D2PRINTK("gred_dequeue: skb has bad tcindex %x\n", | ||
319 | tc_index_to_dp(skb)); | ||
320 | } | 340 | } |
321 | 341 | ||
322 | qdisc_drop(skb, sch); | 342 | qdisc_drop(skb, sch); |