diff options
author | Jarek Poplawski <jarkao2@gmail.com> | 2008-10-31 00:45:55 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-10-31 00:45:55 -0700 |
commit | 8e3af97899db433111287e07d5105189f56fe191 (patch) | |
tree | 40e7779ea4b587c9c3b882018ccaac1b53419f1c /net/sched/sch_multiq.c | |
parent | 99c0db26797edb39cf83c8c5f8972067f5426b4e (diff) |
pkt_sched: Add qdisc->ops->peek() implementation.
Add qdisc->ops->peek() implementation for work-conserving qdiscs.
With feedback from Patrick McHardy.
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/sch_multiq.c')
-rw-r--r-- | net/sched/sch_multiq.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c index 915f3149dde..155648d23b7 100644 --- a/net/sched/sch_multiq.c +++ b/net/sched/sch_multiq.c @@ -155,6 +155,34 @@ static struct sk_buff *multiq_dequeue(struct Qdisc *sch) } +static struct sk_buff *multiq_peek(struct Qdisc *sch) +{ + struct multiq_sched_data *q = qdisc_priv(sch); + unsigned int curband = q->curband; + struct Qdisc *qdisc; + struct sk_buff *skb; + int band; + + for (band = 0; band < q->bands; band++) { + /* cycle through bands to ensure fairness */ + curband++; + if (curband >= q->bands) + curband = 0; + + /* Check that target subqueue is available before + * pulling an skb to avoid excessive requeues + */ + if (!__netif_subqueue_stopped(qdisc_dev(sch), curband)) { + qdisc = q->queues[curband]; + skb = qdisc->ops->peek(qdisc); + if (skb) + return skb; + } + } + return NULL; + +} + static unsigned int multiq_drop(struct Qdisc *sch) { struct multiq_sched_data *q = qdisc_priv(sch); @@ -451,6 +479,7 @@ static struct Qdisc_ops multiq_qdisc_ops __read_mostly = { .priv_size = sizeof(struct multiq_sched_data), .enqueue = multiq_enqueue, .dequeue = multiq_dequeue, + .peek = multiq_peek, .requeue = multiq_requeue, .drop = multiq_drop, .init = multiq_init, |