diff options
Diffstat (limited to 'net/sched/sch_atm.c')
-rw-r--r-- | net/sched/sch_atm.c | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 43d37256c15e..2a8b83af7c47 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c | |||
@@ -62,7 +62,7 @@ struct atm_qdisc_data { | |||
62 | struct atm_flow_data link; /* unclassified skbs go here */ | 62 | struct atm_flow_data link; /* unclassified skbs go here */ |
63 | struct atm_flow_data *flows; /* NB: "link" is also on this | 63 | struct atm_flow_data *flows; /* NB: "link" is also on this |
64 | list */ | 64 | list */ |
65 | struct tasklet_struct task; /* requeue tasklet */ | 65 | struct tasklet_struct task; /* dequeue tasklet */ |
66 | }; | 66 | }; |
67 | 67 | ||
68 | /* ------------------------- Class/flow operations ------------------------- */ | 68 | /* ------------------------- Class/flow operations ------------------------- */ |
@@ -102,7 +102,8 @@ static int atm_tc_graft(struct Qdisc *sch, unsigned long arg, | |||
102 | return -EINVAL; | 102 | return -EINVAL; |
103 | if (!new) | 103 | if (!new) |
104 | new = &noop_qdisc; | 104 | new = &noop_qdisc; |
105 | *old = xchg(&flow->q, new); | 105 | *old = flow->q; |
106 | flow->q = new; | ||
106 | if (*old) | 107 | if (*old) |
107 | qdisc_reset(*old); | 108 | qdisc_reset(*old); |
108 | return 0; | 109 | return 0; |
@@ -480,11 +481,14 @@ static void sch_atm_dequeue(unsigned long data) | |||
480 | * If traffic is properly shaped, this won't generate nasty | 481 | * If traffic is properly shaped, this won't generate nasty |
481 | * little bursts. Otherwise, it may ... (but that's okay) | 482 | * little bursts. Otherwise, it may ... (but that's okay) |
482 | */ | 483 | */ |
483 | while ((skb = flow->q->dequeue(flow->q))) { | 484 | while ((skb = flow->q->ops->peek(flow->q))) { |
484 | if (!atm_may_send(flow->vcc, skb->truesize)) { | 485 | if (!atm_may_send(flow->vcc, skb->truesize)) |
485 | (void)flow->q->ops->requeue(skb, flow->q); | ||
486 | break; | 486 | break; |
487 | } | 487 | |
488 | skb = qdisc_dequeue_peeked(flow->q); | ||
489 | if (unlikely(!skb)) | ||
490 | break; | ||
491 | |||
488 | pr_debug("atm_tc_dequeue: sending on class %p\n", flow); | 492 | pr_debug("atm_tc_dequeue: sending on class %p\n", flow); |
489 | /* remove any LL header somebody else has attached */ | 493 | /* remove any LL header somebody else has attached */ |
490 | skb_pull(skb, skb_network_offset(skb)); | 494 | skb_pull(skb, skb_network_offset(skb)); |
@@ -516,27 +520,19 @@ static struct sk_buff *atm_tc_dequeue(struct Qdisc *sch) | |||
516 | 520 | ||
517 | pr_debug("atm_tc_dequeue(sch %p,[qdisc %p])\n", sch, p); | 521 | pr_debug("atm_tc_dequeue(sch %p,[qdisc %p])\n", sch, p); |
518 | tasklet_schedule(&p->task); | 522 | tasklet_schedule(&p->task); |
519 | skb = p->link.q->dequeue(p->link.q); | 523 | skb = qdisc_dequeue_peeked(p->link.q); |
520 | if (skb) | 524 | if (skb) |
521 | sch->q.qlen--; | 525 | sch->q.qlen--; |
522 | return skb; | 526 | return skb; |
523 | } | 527 | } |
524 | 528 | ||
525 | static int atm_tc_requeue(struct sk_buff *skb, struct Qdisc *sch) | 529 | static struct sk_buff *atm_tc_peek(struct Qdisc *sch) |
526 | { | 530 | { |
527 | struct atm_qdisc_data *p = qdisc_priv(sch); | 531 | struct atm_qdisc_data *p = qdisc_priv(sch); |
528 | int ret; | ||
529 | 532 | ||
530 | pr_debug("atm_tc_requeue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p); | 533 | pr_debug("atm_tc_peek(sch %p,[qdisc %p])\n", sch, p); |
531 | ret = p->link.q->ops->requeue(skb, p->link.q); | 534 | |
532 | if (!ret) { | 535 | return p->link.q->ops->peek(p->link.q); |
533 | sch->q.qlen++; | ||
534 | sch->qstats.requeues++; | ||
535 | } else if (net_xmit_drop_count(ret)) { | ||
536 | sch->qstats.drops++; | ||
537 | p->link.qstats.drops++; | ||
538 | } | ||
539 | return ret; | ||
540 | } | 536 | } |
541 | 537 | ||
542 | static unsigned int atm_tc_drop(struct Qdisc *sch) | 538 | static unsigned int atm_tc_drop(struct Qdisc *sch) |
@@ -694,7 +690,7 @@ static struct Qdisc_ops atm_qdisc_ops __read_mostly = { | |||
694 | .priv_size = sizeof(struct atm_qdisc_data), | 690 | .priv_size = sizeof(struct atm_qdisc_data), |
695 | .enqueue = atm_tc_enqueue, | 691 | .enqueue = atm_tc_enqueue, |
696 | .dequeue = atm_tc_dequeue, | 692 | .dequeue = atm_tc_dequeue, |
697 | .requeue = atm_tc_requeue, | 693 | .peek = atm_tc_peek, |
698 | .drop = atm_tc_drop, | 694 | .drop = atm_tc_drop, |
699 | .init = atm_tc_init, | 695 | .init = atm_tc_init, |
700 | .reset = atm_tc_reset, | 696 | .reset = atm_tc_reset, |