aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_gred.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_gred.c')
-rw-r--r--net/sched/sch_gred.c27
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
64struct gred_sched_data; 65struct gred_sched_data;
65struct gred_sched; 66struct 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
157static inline u16 tc_index_to_dp(struct sk_buff *skb)
158{
159 return skb->tc_index & GRED_VQ_MASK;
160}
161
156static int 162static int
157gred_enqueue(struct sk_buff *skb, struct Qdisc* sch) 163gred_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:
245static int 253static int
246gred_requeue(struct sk_buff *skb, struct Qdisc* sch) 254gred_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);