diff options
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 915f3149dde2..155648d23b7c 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, |