diff options
author | Jarek Poplawski <jarkao2@gmail.com> | 2008-10-31 03:45:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-10-31 03:45:55 -0400 |
commit | 8e3af97899db433111287e07d5105189f56fe191 (patch) | |
tree | 40e7779ea4b587c9c3b882018ccaac1b53419f1c /net | |
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')
-rw-r--r-- | net/sched/sch_atm.c | 10 | ||||
-rw-r--r-- | net/sched/sch_blackhole.c | 1 | ||||
-rw-r--r-- | net/sched/sch_dsmark.c | 10 | ||||
-rw-r--r-- | net/sched/sch_gred.c | 1 | ||||
-rw-r--r-- | net/sched/sch_multiq.c | 29 | ||||
-rw-r--r-- | net/sched/sch_netem.c | 1 | ||||
-rw-r--r-- | net/sched/sch_red.c | 9 | ||||
-rw-r--r-- | net/sched/sch_teql.c | 8 |
8 files changed, 69 insertions, 0 deletions
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 43d37256c15e..f9eac0818d18 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c | |||
@@ -522,6 +522,15 @@ static struct sk_buff *atm_tc_dequeue(struct Qdisc *sch) | |||
522 | return skb; | 522 | return skb; |
523 | } | 523 | } |
524 | 524 | ||
525 | static struct sk_buff *atm_tc_peek(struct Qdisc *sch) | ||
526 | { | ||
527 | struct atm_qdisc_data *p = qdisc_priv(sch); | ||
528 | |||
529 | pr_debug("atm_tc_peek(sch %p,[qdisc %p])\n", sch, p); | ||
530 | |||
531 | return p->link.q->ops->peek(p->link.q); | ||
532 | } | ||
533 | |||
525 | static int atm_tc_requeue(struct sk_buff *skb, struct Qdisc *sch) | 534 | static int atm_tc_requeue(struct sk_buff *skb, struct Qdisc *sch) |
526 | { | 535 | { |
527 | struct atm_qdisc_data *p = qdisc_priv(sch); | 536 | struct atm_qdisc_data *p = qdisc_priv(sch); |
@@ -694,6 +703,7 @@ static struct Qdisc_ops atm_qdisc_ops __read_mostly = { | |||
694 | .priv_size = sizeof(struct atm_qdisc_data), | 703 | .priv_size = sizeof(struct atm_qdisc_data), |
695 | .enqueue = atm_tc_enqueue, | 704 | .enqueue = atm_tc_enqueue, |
696 | .dequeue = atm_tc_dequeue, | 705 | .dequeue = atm_tc_dequeue, |
706 | .peek = atm_tc_peek, | ||
697 | .requeue = atm_tc_requeue, | 707 | .requeue = atm_tc_requeue, |
698 | .drop = atm_tc_drop, | 708 | .drop = atm_tc_drop, |
699 | .init = atm_tc_init, | 709 | .init = atm_tc_init, |
diff --git a/net/sched/sch_blackhole.c b/net/sched/sch_blackhole.c index 507fb488bc98..094a874b48bc 100644 --- a/net/sched/sch_blackhole.c +++ b/net/sched/sch_blackhole.c | |||
@@ -33,6 +33,7 @@ static struct Qdisc_ops blackhole_qdisc_ops __read_mostly = { | |||
33 | .priv_size = 0, | 33 | .priv_size = 0, |
34 | .enqueue = blackhole_enqueue, | 34 | .enqueue = blackhole_enqueue, |
35 | .dequeue = blackhole_dequeue, | 35 | .dequeue = blackhole_dequeue, |
36 | .peek = blackhole_dequeue, | ||
36 | .owner = THIS_MODULE, | 37 | .owner = THIS_MODULE, |
37 | }; | 38 | }; |
38 | 39 | ||
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index ba43aab3a851..3e491479ea86 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c | |||
@@ -313,6 +313,15 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch) | |||
313 | return skb; | 313 | return skb; |
314 | } | 314 | } |
315 | 315 | ||
316 | static struct sk_buff *dsmark_peek(struct Qdisc *sch) | ||
317 | { | ||
318 | struct dsmark_qdisc_data *p = qdisc_priv(sch); | ||
319 | |||
320 | pr_debug("dsmark_peek(sch %p,[qdisc %p])\n", sch, p); | ||
321 | |||
322 | return p->q->ops->peek(p->q); | ||
323 | } | ||
324 | |||
316 | static int dsmark_requeue(struct sk_buff *skb, struct Qdisc *sch) | 325 | static int dsmark_requeue(struct sk_buff *skb, struct Qdisc *sch) |
317 | { | 326 | { |
318 | struct dsmark_qdisc_data *p = qdisc_priv(sch); | 327 | struct dsmark_qdisc_data *p = qdisc_priv(sch); |
@@ -496,6 +505,7 @@ static struct Qdisc_ops dsmark_qdisc_ops __read_mostly = { | |||
496 | .priv_size = sizeof(struct dsmark_qdisc_data), | 505 | .priv_size = sizeof(struct dsmark_qdisc_data), |
497 | .enqueue = dsmark_enqueue, | 506 | .enqueue = dsmark_enqueue, |
498 | .dequeue = dsmark_dequeue, | 507 | .dequeue = dsmark_dequeue, |
508 | .peek = dsmark_peek, | ||
499 | .requeue = dsmark_requeue, | 509 | .requeue = dsmark_requeue, |
500 | .drop = dsmark_drop, | 510 | .drop = dsmark_drop, |
501 | .init = dsmark_init, | 511 | .init = dsmark_init, |
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index c1ad6b8de105..cb20ee3b9fc2 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c | |||
@@ -602,6 +602,7 @@ static struct Qdisc_ops gred_qdisc_ops __read_mostly = { | |||
602 | .priv_size = sizeof(struct gred_sched), | 602 | .priv_size = sizeof(struct gred_sched), |
603 | .enqueue = gred_enqueue, | 603 | .enqueue = gred_enqueue, |
604 | .dequeue = gred_dequeue, | 604 | .dequeue = gred_dequeue, |
605 | .peek = qdisc_peek_head, | ||
605 | .requeue = gred_requeue, | 606 | .requeue = gred_requeue, |
606 | .drop = gred_drop, | 607 | .drop = gred_drop, |
607 | .init = gred_init, | 608 | .init = gred_init, |
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) | |||
155 | 155 | ||
156 | } | 156 | } |
157 | 157 | ||
158 | static struct sk_buff *multiq_peek(struct Qdisc *sch) | ||
159 | { | ||
160 | struct multiq_sched_data *q = qdisc_priv(sch); | ||
161 | unsigned int curband = q->curband; | ||
162 | struct Qdisc *qdisc; | ||
163 | struct sk_buff *skb; | ||
164 | int band; | ||
165 | |||
166 | for (band = 0; band < q->bands; band++) { | ||
167 | /* cycle through bands to ensure fairness */ | ||
168 | curband++; | ||
169 | if (curband >= q->bands) | ||
170 | curband = 0; | ||
171 | |||
172 | /* Check that target subqueue is available before | ||
173 | * pulling an skb to avoid excessive requeues | ||
174 | */ | ||
175 | if (!__netif_subqueue_stopped(qdisc_dev(sch), curband)) { | ||
176 | qdisc = q->queues[curband]; | ||
177 | skb = qdisc->ops->peek(qdisc); | ||
178 | if (skb) | ||
179 | return skb; | ||
180 | } | ||
181 | } | ||
182 | return NULL; | ||
183 | |||
184 | } | ||
185 | |||
158 | static unsigned int multiq_drop(struct Qdisc *sch) | 186 | static unsigned int multiq_drop(struct Qdisc *sch) |
159 | { | 187 | { |
160 | struct multiq_sched_data *q = qdisc_priv(sch); | 188 | struct multiq_sched_data *q = qdisc_priv(sch); |
@@ -451,6 +479,7 @@ static struct Qdisc_ops multiq_qdisc_ops __read_mostly = { | |||
451 | .priv_size = sizeof(struct multiq_sched_data), | 479 | .priv_size = sizeof(struct multiq_sched_data), |
452 | .enqueue = multiq_enqueue, | 480 | .enqueue = multiq_enqueue, |
453 | .dequeue = multiq_dequeue, | 481 | .dequeue = multiq_dequeue, |
482 | .peek = multiq_peek, | ||
454 | .requeue = multiq_requeue, | 483 | .requeue = multiq_requeue, |
455 | .drop = multiq_drop, | 484 | .drop = multiq_drop, |
456 | .init = multiq_init, | 485 | .init = multiq_init, |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index a11959908d9a..2898d9dc31eb 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
@@ -541,6 +541,7 @@ static struct Qdisc_ops tfifo_qdisc_ops __read_mostly = { | |||
541 | .priv_size = sizeof(struct fifo_sched_data), | 541 | .priv_size = sizeof(struct fifo_sched_data), |
542 | .enqueue = tfifo_enqueue, | 542 | .enqueue = tfifo_enqueue, |
543 | .dequeue = qdisc_dequeue_head, | 543 | .dequeue = qdisc_dequeue_head, |
544 | .peek = qdisc_peek_head, | ||
544 | .requeue = qdisc_requeue, | 545 | .requeue = qdisc_requeue, |
545 | .drop = qdisc_queue_drop, | 546 | .drop = qdisc_queue_drop, |
546 | .init = tfifo_init, | 547 | .init = tfifo_init, |
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index 5da05839e225..7abc51454c2d 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c | |||
@@ -140,6 +140,14 @@ static struct sk_buff * red_dequeue(struct Qdisc* sch) | |||
140 | return skb; | 140 | return skb; |
141 | } | 141 | } |
142 | 142 | ||
143 | static struct sk_buff * red_peek(struct Qdisc* sch) | ||
144 | { | ||
145 | struct red_sched_data *q = qdisc_priv(sch); | ||
146 | struct Qdisc *child = q->qdisc; | ||
147 | |||
148 | return child->ops->peek(child); | ||
149 | } | ||
150 | |||
143 | static unsigned int red_drop(struct Qdisc* sch) | 151 | static unsigned int red_drop(struct Qdisc* sch) |
144 | { | 152 | { |
145 | struct red_sched_data *q = qdisc_priv(sch); | 153 | struct red_sched_data *q = qdisc_priv(sch); |
@@ -361,6 +369,7 @@ static struct Qdisc_ops red_qdisc_ops __read_mostly = { | |||
361 | .cl_ops = &red_class_ops, | 369 | .cl_ops = &red_class_ops, |
362 | .enqueue = red_enqueue, | 370 | .enqueue = red_enqueue, |
363 | .dequeue = red_dequeue, | 371 | .dequeue = red_dequeue, |
372 | .peek = red_peek, | ||
364 | .requeue = red_requeue, | 373 | .requeue = red_requeue, |
365 | .drop = red_drop, | 374 | .drop = red_drop, |
366 | .init = red_init, | 375 | .init = red_init, |
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index d35ef059abb1..bf03e7fa1849 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c | |||
@@ -123,6 +123,13 @@ teql_dequeue(struct Qdisc* sch) | |||
123 | return skb; | 123 | return skb; |
124 | } | 124 | } |
125 | 125 | ||
126 | static struct sk_buff * | ||
127 | teql_peek(struct Qdisc* sch) | ||
128 | { | ||
129 | /* teql is meant to be used as root qdisc */ | ||
130 | return NULL; | ||
131 | } | ||
132 | |||
126 | static __inline__ void | 133 | static __inline__ void |
127 | teql_neigh_release(struct neighbour *n) | 134 | teql_neigh_release(struct neighbour *n) |
128 | { | 135 | { |
@@ -433,6 +440,7 @@ static __init void teql_master_setup(struct net_device *dev) | |||
433 | 440 | ||
434 | ops->enqueue = teql_enqueue; | 441 | ops->enqueue = teql_enqueue; |
435 | ops->dequeue = teql_dequeue; | 442 | ops->dequeue = teql_dequeue; |
443 | ops->peek = teql_peek; | ||
436 | ops->requeue = teql_requeue; | 444 | ops->requeue = teql_requeue; |
437 | ops->init = teql_qdisc_init; | 445 | ops->init = teql_qdisc_init; |
438 | ops->reset = teql_reset; | 446 | ops->reset = teql_reset; |