diff options
Diffstat (limited to 'net/sched/sch_gred.c')
-rw-r--r-- | net/sched/sch_gred.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index 95c5f2cf3fdf..38dab959feed 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c | |||
@@ -60,6 +60,7 @@ | |||
60 | #endif | 60 | #endif |
61 | 61 | ||
62 | #define GRED_DEF_PRIO (MAX_DPs / 2) | 62 | #define GRED_DEF_PRIO (MAX_DPs / 2) |
63 | #define GRED_VQ_MASK (MAX_DPs - 1) | ||
63 | 64 | ||
64 | struct gred_sched_data; | 65 | struct gred_sched_data; |
65 | struct gred_sched; | 66 | struct gred_sched; |
@@ -153,6 +154,11 @@ static inline unsigned int gred_backlog(struct gred_sched *table, | |||
153 | return q->backlog; | 154 | return q->backlog; |
154 | } | 155 | } |
155 | 156 | ||
157 | static inline u16 tc_index_to_dp(struct sk_buff *skb) | ||
158 | { | ||
159 | return skb->tc_index & GRED_VQ_MASK; | ||
160 | } | ||
161 | |||
156 | static int | 162 | static int |
157 | gred_enqueue(struct sk_buff *skb, struct Qdisc* sch) | 163 | gred_enqueue(struct sk_buff *skb, struct Qdisc* sch) |
158 | { | 164 | { |
@@ -160,14 +166,16 @@ gred_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
160 | struct gred_sched *t= qdisc_priv(sch); | 166 | struct gred_sched *t= qdisc_priv(sch); |
161 | unsigned long qavg = 0; | 167 | unsigned long qavg = 0; |
162 | int i=0; | 168 | int i=0; |
169 | u16 dp; | ||
163 | 170 | ||
164 | if (!t->initd && skb_queue_len(&sch->q) < (sch->dev->tx_queue_len ? : 1)) { | 171 | if (!t->initd && skb_queue_len(&sch->q) < (sch->dev->tx_queue_len ? : 1)) { |
165 | D2PRINTK("NO GRED Queues setup yet! Enqueued anyway\n"); | 172 | D2PRINTK("NO GRED Queues setup yet! Enqueued anyway\n"); |
166 | goto do_enqueue; | 173 | goto do_enqueue; |
167 | } | 174 | } |
168 | 175 | ||
176 | dp = tc_index_to_dp(skb); | ||
169 | 177 | ||
170 | if ( ((skb->tc_index&0xf) > (t->DPs -1)) || !(q=t->tab[skb->tc_index&0xf])) { | 178 | if (dp >= t->DPs || (q = t->tab[dp]) == NULL) { |
171 | printk("GRED: setting to default (%d)\n ",t->def); | 179 | printk("GRED: setting to default (%d)\n ",t->def); |
172 | if (!(q=t->tab[t->def])) { | 180 | if (!(q=t->tab[t->def])) { |
173 | DPRINTK("GRED: setting to default FAILED! dropping!! " | 181 | DPRINTK("GRED: setting to default FAILED! dropping!! " |
@@ -176,7 +184,7 @@ gred_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
176 | } | 184 | } |
177 | /* fix tc_index? --could be controvesial but needed for | 185 | /* fix tc_index? --could be controvesial but needed for |
178 | requeueing */ | 186 | requeueing */ |
179 | skb->tc_index=(skb->tc_index&0xfffffff0) | t->def; | 187 | skb->tc_index=(skb->tc_index & ~GRED_VQ_MASK) | t->def; |
180 | } | 188 | } |
181 | 189 | ||
182 | D2PRINTK("gred_enqueue virtualQ 0x%x classid %x backlog %d " | 190 | D2PRINTK("gred_enqueue virtualQ 0x%x classid %x backlog %d " |
@@ -245,9 +253,8 @@ congestion_drop: | |||
245 | static int | 253 | static int |
246 | gred_requeue(struct sk_buff *skb, struct Qdisc* sch) | 254 | gred_requeue(struct sk_buff *skb, struct Qdisc* sch) |
247 | { | 255 | { |
248 | struct gred_sched_data *q; | 256 | struct gred_sched *t = qdisc_priv(sch); |
249 | struct gred_sched *t= qdisc_priv(sch); | 257 | struct gred_sched_data *q = t->tab[tc_index_to_dp(skb)]; |
250 | q= t->tab[(skb->tc_index&0xf)]; | ||
251 | /* error checking here -- probably unnecessary */ | 258 | /* error checking here -- probably unnecessary */ |
252 | 259 | ||
253 | if (red_is_idling(&q->parms)) | 260 | if (red_is_idling(&q->parms)) |
@@ -267,13 +274,14 @@ gred_dequeue(struct Qdisc* sch) | |||
267 | skb = qdisc_dequeue_head(sch); | 274 | skb = qdisc_dequeue_head(sch); |
268 | 275 | ||
269 | if (skb) { | 276 | if (skb) { |
270 | q= t->tab[(skb->tc_index&0xf)]; | 277 | q = t->tab[tc_index_to_dp(skb)]; |
271 | if (q) { | 278 | if (q) { |
272 | q->backlog -= skb->len; | 279 | q->backlog -= skb->len; |
273 | if (!q->backlog && !gred_wred_mode(t)) | 280 | if (!q->backlog && !gred_wred_mode(t)) |
274 | red_start_of_idle_period(&q->parms); | 281 | red_start_of_idle_period(&q->parms); |
275 | } else { | 282 | } else { |
276 | D2PRINTK("gred_dequeue: skb has bad tcindex %x\n",skb->tc_index&0xf); | 283 | D2PRINTK("gred_dequeue: skb has bad tcindex %x\n", |
284 | tc_index_to_dp(skb)); | ||
277 | } | 285 | } |
278 | return skb; | 286 | return skb; |
279 | } | 287 | } |
@@ -300,14 +308,15 @@ static unsigned int gred_drop(struct Qdisc* sch) | |||
300 | skb = qdisc_dequeue_tail(sch); | 308 | skb = qdisc_dequeue_tail(sch); |
301 | if (skb) { | 309 | if (skb) { |
302 | unsigned int len = skb->len; | 310 | unsigned int len = skb->len; |
303 | q= t->tab[(skb->tc_index&0xf)]; | 311 | q = t->tab[tc_index_to_dp(skb)]; |
304 | if (q) { | 312 | if (q) { |
305 | q->backlog -= len; | 313 | q->backlog -= len; |
306 | q->stats.other++; | 314 | q->stats.other++; |
307 | if (!q->backlog && !gred_wred_mode(t)) | 315 | if (!q->backlog && !gred_wred_mode(t)) |
308 | red_start_of_idle_period(&q->parms); | 316 | red_start_of_idle_period(&q->parms); |
309 | } else { | 317 | } else { |
310 | D2PRINTK("gred_dequeue: skb has bad tcindex %x\n",skb->tc_index&0xf); | 318 | D2PRINTK("gred_dequeue: skb has bad tcindex %x\n", |
319 | tc_index_to_dp(skb)); | ||
311 | } | 320 | } |
312 | 321 | ||
313 | qdisc_drop(skb, sch); | 322 | qdisc_drop(skb, sch); |