Skip to content

Commit

Permalink
[PKT_SCHED]: GRED: Improve error handling and messages
Browse files Browse the repository at this point in the history
Try to enqueue packets if we cannot associate it with a VQ, this
basically means that the default VQ has not been set up yet.

We must check if the VQ still exists while requeueing, the VQ
might have been changed between dequeue and the requeue of the
underlying qdisc.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
  • Loading branch information
Thomas Graf authored and Thomas Graf committed Nov 5, 2005
1 parent 716a1b4 commit 18e3fb8
Showing 1 changed file with 44 additions and 24 deletions.
68 changes: 44 additions & 24 deletions net/sched/sch_gred.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,20 +176,24 @@ gred_enqueue(struct sk_buff *skb, struct Qdisc* sch)
dp = tc_index_to_dp(skb);

if (dp >= t->DPs || (q = t->tab[dp]) == NULL) {
printk("GRED: setting to default (%d)\n ",t->def);
if (!(q=t->tab[t->def])) {
DPRINTK("GRED: setting to default FAILED! dropping!! "
"(%d)\n ", t->def);
goto drop;
dp = t->def;

if ((q = t->tab[dp]) == NULL) {
/* Pass through packets not assigned to a DP
* if no default DP has been configured. This
* allows for DP flows to be left untouched.
*/
if (skb_queue_len(&sch->q) < sch->dev->tx_queue_len)
return qdisc_enqueue_tail(skb, sch);
else
goto drop;
}

/* fix tc_index? --could be controvesial but needed for
requeueing */
skb->tc_index=(skb->tc_index & ~GRED_VQ_MASK) | t->def;
skb->tc_index = (skb->tc_index & ~GRED_VQ_MASK) | dp;
}

D2PRINTK("gred_enqueue virtualQ 0x%x classid %x backlog %d "
"general backlog %d\n",skb->tc_index&0xf,sch->handle,q->backlog,
sch->qstats.backlog);
/* sum up all the qaves of prios <= to ours to get the new qave*/
if (!gred_wred_mode(t) && gred_rio_mode(t)) {
for (i=0;i<t->DPs;i++) {
Expand Down Expand Up @@ -254,13 +258,20 @@ static int
gred_requeue(struct sk_buff *skb, struct Qdisc* sch)
{
struct gred_sched *t = qdisc_priv(sch);
struct gred_sched_data *q = t->tab[tc_index_to_dp(skb)];
/* error checking here -- probably unnecessary */
struct gred_sched_data *q;
u16 dp = tc_index_to_dp(skb);

if (red_is_idling(&q->parms))
red_end_of_idle_period(&q->parms);
if (dp >= t->DPs || (q = t->tab[dp]) == NULL) {
if (net_ratelimit())
printk(KERN_WARNING "GRED: Unable to relocate VQ 0x%x "
"for requeue, screwing up backlog.\n",
tc_index_to_dp(skb));
} else {
if (red_is_idling(&q->parms))
red_end_of_idle_period(&q->parms);
q->backlog += skb->len;
}

q->backlog += skb->len;
return qdisc_requeue(skb, sch);
}

Expand All @@ -274,15 +285,20 @@ gred_dequeue(struct Qdisc* sch)
skb = qdisc_dequeue_head(sch);

if (skb) {
q = t->tab[tc_index_to_dp(skb)];
if (q) {
u16 dp = tc_index_to_dp(skb);

if (dp >= t->DPs || (q = t->tab[dp]) == NULL) {
if (net_ratelimit())
printk(KERN_WARNING "GRED: Unable to relocate "
"VQ 0x%x after dequeue, screwing up "
"backlog.\n", tc_index_to_dp(skb));
} else {
q->backlog -= skb->len;

if (!q->backlog && !gred_wred_mode(t))
red_start_of_idle_period(&q->parms);
} else {
D2PRINTK("gred_dequeue: skb has bad tcindex %x\n",
tc_index_to_dp(skb));
}

return skb;
}

Expand All @@ -308,15 +324,19 @@ static unsigned int gred_drop(struct Qdisc* sch)
skb = qdisc_dequeue_tail(sch);
if (skb) {
unsigned int len = skb->len;
q = t->tab[tc_index_to_dp(skb)];
if (q) {
u16 dp = tc_index_to_dp(skb);

if (dp >= t->DPs || (q = t->tab[dp]) == NULL) {
if (net_ratelimit())
printk(KERN_WARNING "GRED: Unable to relocate "
"VQ 0x%x while dropping, screwing up "
"backlog.\n", tc_index_to_dp(skb));
} else {
q->backlog -= len;
q->stats.other++;

if (!q->backlog && !gred_wred_mode(t))
red_start_of_idle_period(&q->parms);
} else {
D2PRINTK("gred_dequeue: skb has bad tcindex %x\n",
tc_index_to_dp(skb));
}

qdisc_drop(skb, sch);
Expand Down

0 comments on commit 18e3fb8

Please sign in to comment.