summaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-03-27 23:54:12 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-03-27 23:54:12 +0000
commitd3e71cb08747743fce908122bab08b479eb403a5 (patch)
treecbec6948fdbdee9af81cf3ecfb504070d2745d7b /net/sched
parentfe7ff1706e323d0e5ed83972960a1ecc1ee538b3 (diff)
Merge with Linux 2.3.99-pre3.
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/sch_atm.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index a3b25f2a7..021d7d658 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -276,7 +276,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
goto err_out;
}
/* @@@ should check if the socket is really operational or we'll crash
- on vcc->dev->ops->send */
+ on vcc->send */
if (classid) {
if (TC_H_MAJ(classid ^ sch->handle)) {
DPRINTK("atm_tc_change: classid mismatch\n");
@@ -449,8 +449,21 @@ static int atm_tc_enqueue(struct sk_buff *skb,struct Qdisc *sch)
sch->stats.packets++;
flow->stats.bytes += skb->len;
flow->stats.packets++;
- sch->q.qlen++;
- return 0;
+ /*
+ * Okay, this may seem weird. We pretend we've dropped the packet if
+ * it goes via ATM. The reason for this is that the outer qdisc
+ * expects to be able to q->dequeue the packet later on if we return
+ * success at this place. Also, sch->q.qdisc needs to reflect whether
+ * there is a packet egligible for dequeuing or not. Note that the
+ * statistics of the outer qdisc are necessarily wrong because of all
+ * this. There's currently no correct solution for this.
+ */
+ if (flow == &p->link) {
+ sch->q.qlen++;
+ return 0;
+ }
+ tasklet_schedule(&p->task);
+ return NET_XMIT_BYPASS;
}
@@ -477,11 +490,9 @@ static void sch_atm_dequeue(unsigned long data)
*/
while ((skb = flow->q->dequeue(flow->q))) {
if (!atm_may_send(flow->vcc,skb->truesize)) {
- if (flow->q->ops->requeue(skb,flow->q))
- sch->q.qlen--;
+ (void) flow->q->ops->requeue(skb,flow->q);
break;
}
- sch->q.qlen--;
D2PRINTK("atm_tc_deqeueue: sending on class %p\n",flow);
/* remove any LL header somebody else has attached */
skb_pull(skb,(char *) skb->nh.iph-(char *) skb->data);
@@ -501,7 +512,7 @@ static void sch_atm_dequeue(unsigned long data)
atomic_add(skb->truesize,&flow->vcc->tx_inuse);
ATM_SKB(skb)->iovcnt = 0;
/* atm.atm_options are already set by atm_tc_enqueue */
- (void) flow->vcc->dev->ops->send(flow->vcc,skb);
+ (void) flow->vcc->send(flow->vcc,skb);
}
}