Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jarek Poplawski and committed by
David S. Miller
8e3af978 99c0db26

+69
+10
net/sched/sch_atm.c
··· 522 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 534 static int atm_tc_requeue(struct sk_buff *skb, struct Qdisc *sch) 526 535 { 527 536 struct atm_qdisc_data *p = qdisc_priv(sch); ··· 703 694 .priv_size = sizeof(struct atm_qdisc_data), 704 695 .enqueue = atm_tc_enqueue, 705 696 .dequeue = atm_tc_dequeue, 697 + .peek = atm_tc_peek, 706 698 .requeue = atm_tc_requeue, 707 699 .drop = atm_tc_drop, 708 700 .init = atm_tc_init,
+1
net/sched/sch_blackhole.c
··· 33 33 .priv_size = 0, 34 34 .enqueue = blackhole_enqueue, 35 35 .dequeue = blackhole_dequeue, 36 + .peek = blackhole_dequeue, 36 37 .owner = THIS_MODULE, 37 38 }; 38 39
+10
net/sched/sch_dsmark.c
··· 313 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 325 static int dsmark_requeue(struct sk_buff *skb, struct Qdisc *sch) 317 326 { 318 327 struct dsmark_qdisc_data *p = qdisc_priv(sch); ··· 505 496 .priv_size = sizeof(struct dsmark_qdisc_data), 506 497 .enqueue = dsmark_enqueue, 507 498 .dequeue = dsmark_dequeue, 499 + .peek = dsmark_peek, 508 500 .requeue = dsmark_requeue, 509 501 .drop = dsmark_drop, 510 502 .init = dsmark_init,
+1
net/sched/sch_gred.c
··· 602 602 .priv_size = sizeof(struct gred_sched), 603 603 .enqueue = gred_enqueue, 604 604 .dequeue = gred_dequeue, 605 + .peek = qdisc_peek_head, 605 606 .requeue = gred_requeue, 606 607 .drop = gred_drop, 607 608 .init = gred_init,
+29
net/sched/sch_multiq.c
··· 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 186 static unsigned int multiq_drop(struct Qdisc *sch) 159 187 { 160 188 struct multiq_sched_data *q = qdisc_priv(sch); ··· 479 451 .priv_size = sizeof(struct multiq_sched_data), 480 452 .enqueue = multiq_enqueue, 481 453 .dequeue = multiq_dequeue, 454 + .peek = multiq_peek, 482 455 .requeue = multiq_requeue, 483 456 .drop = multiq_drop, 484 457 .init = multiq_init,
+1
net/sched/sch_netem.c
··· 541 541 .priv_size = sizeof(struct fifo_sched_data), 542 542 .enqueue = tfifo_enqueue, 543 543 .dequeue = qdisc_dequeue_head, 544 + .peek = qdisc_peek_head, 544 545 .requeue = qdisc_requeue, 545 546 .drop = qdisc_queue_drop, 546 547 .init = tfifo_init,
+9
net/sched/sch_red.c
··· 140 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 151 static unsigned int red_drop(struct Qdisc* sch) 144 152 { 145 153 struct red_sched_data *q = qdisc_priv(sch); ··· 369 361 .cl_ops = &red_class_ops, 370 362 .enqueue = red_enqueue, 371 363 .dequeue = red_dequeue, 364 + .peek = red_peek, 372 365 .requeue = red_requeue, 373 366 .drop = red_drop, 374 367 .init = red_init,
+8
net/sched/sch_teql.c
··· 123 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 133 static __inline__ void 127 134 teql_neigh_release(struct neighbour *n) 128 135 { ··· 440 433 441 434 ops->enqueue = teql_enqueue; 442 435 ops->dequeue = teql_dequeue; 436 + ops->peek = teql_peek; 443 437 ops->requeue = teql_requeue; 444 438 ops->init = teql_qdisc_init; 445 439 ops->reset = teql_reset;