patch-2.3.42 linux/net/sched/sch_gred.c
Next file: linux/CREDITS
Previous file: linux/net/sched/sch_dsmark.c
Back to the patch index
Back to the overall index
- Lines: 201
- Date:
Mon Jan 31 23:41:14 2000
- Orig file:
v2.3.41/linux/net/sched/sch_gred.c
- Orig date:
Fri Jan 7 19:13:23 2000
diff -u --recursive --new-file v2.3.41/linux/net/sched/sch_gred.c linux/net/sched/sch_gred.c
@@ -10,9 +10,10 @@
* Authors: J Hadi Salim (hadi@nortelnetworks.com) 1998,1999
*
* 991129: - Bug fix with grio mode
- * - a better sing. AvgQ mode with Grio
+ * - a better sing. AvgQ mode with Grio(WRED)
* - A finer grained VQ dequeue based on sugestion
* from Ren Liu
+ * - More error checks
*
*
*
@@ -134,17 +135,10 @@
"general backlog %d\n",skb->tc_index&0xf,sch->handle,q->backlog,
sch->stats.backlog);
/* sum up all the qaves of prios <= to ours to get the new qave*/
- if (t->grio) {
+ if (!t->eqp && t->grio) {
for (i=0;i<t->DPs;i++) {
if ((!t->tab[i]) || (i==q->DP))
continue;
- if (t->tab[i]->prio == q->prio ){
- qave=0;
- t->eqp=1;
- q->qave=t->tab[t->def]->qave;
- q->qidlestart=t->tab[t->def]->qidlestart;
- break;
- }
if ((t->tab[i]->prio < q->prio) && (PSCHED_IS_PASTPERFECT(t->tab[i]->qidlestart)))
qave +=t->tab[i]->qave;
@@ -155,6 +149,12 @@
q->packetsin++;
q->bytesin+=skb->len;
+ if (t->eqp && t->grio) {
+ qave=0;
+ q->qave=t->tab[t->def]->qave;
+ q->qidlestart=t->tab[t->def]->qidlestart;
+ }
+
if (!PSCHED_IS_PASTPERFECT(q->qidlestart)) {
long us_idle;
PSCHED_GET_TIME(now);
@@ -163,7 +163,12 @@
q->qave >>= q->Stab[(us_idle>>q->Scell_log)&0xFF];
} else {
- q->qave += q->backlog - (q->qave >> q->Wlog);
+ if (t->eqp) {
+ q->qave += sch->stats.backlog - (q->qave >> q->Wlog);
+ } else {
+ q->qave += q->backlog - (q->qave >> q->Wlog);
+ }
+
}
@@ -232,18 +237,22 @@
skb = __skb_dequeue(&sch->q);
if (skb) {
- q= t->tab[(skb->tc_index&0xf)];
sch->stats.backlog -= skb->len;
- q->backlog -= skb->len;
- if (!q->backlog && !t->eqp)
- PSCHED_GET_TIME(q->qidlestart);
+ q= t->tab[(skb->tc_index&0xf)];
+ if (q) {
+ q->backlog -= skb->len;
+ if (!q->backlog && !t->eqp)
+ PSCHED_GET_TIME(q->qidlestart);
+ } else {
+ D2PRINTK("gred_dequeue: skb has bad tcindex %x\n",skb->tc_index&0xf);
+ }
return skb;
}
if (t->eqp) {
q= t->tab[t->def];
if (!q)
- printk("no default VQ set: Results will be "
+ D2PRINTK("no default VQ set: Results will be "
"screwed up\n");
else
PSCHED_GET_TIME(q->qidlestart);
@@ -256,31 +265,37 @@
gred_drop(struct Qdisc* sch)
{
struct sk_buff *skb;
- int i;
struct gred_sched_data *q;
struct gred_sched *t= (struct gred_sched *)sch->data;
skb = __skb_dequeue_tail(&sch->q);
if (skb) {
- q= t->tab[(skb->tc_index&0xf)];
sch->stats.backlog -= skb->len;
sch->stats.drops++;
- q->backlog -= skb->len;
- q->other++;
+ q= t->tab[(skb->tc_index&0xf)];
+ if (q) {
+ q->backlog -= skb->len;
+ q->other++;
+ if (!q->backlog && !t->eqp)
+ PSCHED_GET_TIME(q->qidlestart);
+ } else {
+ D2PRINTK("gred_dequeue: skb has bad tcindex %x\n",skb->tc_index&0xf);
+ }
+
kfree_skb(skb);
return 1;
}
-/* could probably do it for a single VQ before freeing the skb */
- for (i=0;i<t->DPs;i++) {
- q= t->tab[i];
- if (!q)
- continue;
- PSCHED_GET_TIME(q->qidlestart);
- }
+ q=t->tab[t->def];
+ if (!q) {
+ D2PRINTK("no default VQ set: Results might be screwed up\n");
+ return 0;
+ }
+ PSCHED_GET_TIME(q->qidlestart);
return 0;
+
}
static void gred_reset(struct Qdisc* sch)
@@ -295,7 +310,6 @@
kfree_skb(skb);
sch->stats.backlog = 0;
-/* could probably do it for a single VQ before freeing the skb */
for (i=0;i<t->DPs;i++) {
q= t->tab[i];
if (!q)
@@ -319,6 +333,7 @@
struct tc_gred_sopt *sopt;
struct rtattr *tb[TCA_GRED_STAB];
struct rtattr *tb2[TCA_GRED_STAB];
+ int i;
if (opt == NULL ||
rtattr_parse(tb, TCA_GRED_STAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) )
@@ -340,13 +355,13 @@
}
- if (!table->DPs || tb[TCA_GRED_PARMS-1] == 0 || tb[TCA_GRED_STAB-1] == 0 ||
+ if (!table->DPs || tb[TCA_GRED_PARMS-1] == 0 || tb[TCA_GRED_STAB-1] == 0 ||
RTA_PAYLOAD(tb[TCA_GRED_PARMS-1]) < sizeof(*ctl) ||
RTA_PAYLOAD(tb[TCA_GRED_STAB-1]) < 256)
- return -EINVAL;
+ return -EINVAL;
- ctl = RTA_DATA(tb[TCA_GRED_PARMS-1]);
- if (ctl->DP > MAX_DPs-1 || ctl->DP <0) {
+ ctl = RTA_DATA(tb[TCA_GRED_PARMS-1]);
+ if (ctl->DP > MAX_DPs-1 || ctl->DP <0) {
/* misbehaving is punished! Put in the default drop probability */
DPRINTK("\nGRED: DP %u not in the proper range fixed. New DP "
"set to default at %d\n",ctl->DP,table->def);
@@ -356,8 +371,8 @@
if (table->tab[ctl->DP] == NULL) {
table->tab[ctl->DP]=kmalloc(sizeof(struct gred_sched_data),
GFP_KERNEL);
- memset(table->tab[ctl->DP], 0, (sizeof(struct gred_sched_data)));
- }
+ memset(table->tab[ctl->DP], 0, (sizeof(struct gred_sched_data)));
+ }
q= table->tab[ctl->DP];
if (table->grio) {
@@ -399,6 +414,19 @@
PSCHED_SET_PASTPERFECT(q->qidlestart);
memcpy(q->Stab, RTA_DATA(tb[TCA_GRED_STAB-1]), 256);
+
+ if ( table->initd && table->grio) {
+ /* this looks ugly but its not in the fast path */
+ for (i=0;i<table->DPs;i++) {
+ if ((!table->tab[i]) || (i==q->DP) )
+ continue;
+ if (table->tab[i]->prio == q->prio ){
+ /* WRED mode detected */
+ table->eqp=1;
+ break;
+ }
+ }
+ }
if (!table->initd) {
table->initd=1;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)