Ver código fonte

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>
Jarek Poplawski 16 anos atrás
pai
commit
8e3af97899

+ 10 - 0
net/sched/sch_atm.c

@@ -522,6 +522,15 @@ static struct sk_buff *atm_tc_dequeue(struct Qdisc *sch)
 	return skb;
 	return skb;
 }
 }
 
 
+static struct sk_buff *atm_tc_peek(struct Qdisc *sch)
+{
+	struct atm_qdisc_data *p = qdisc_priv(sch);
+
+	pr_debug("atm_tc_peek(sch %p,[qdisc %p])\n", sch, p);
+
+	return p->link.q->ops->peek(p->link.q);
+}
+
 static int atm_tc_requeue(struct sk_buff *skb, struct Qdisc *sch)
 static int atm_tc_requeue(struct sk_buff *skb, struct Qdisc *sch)
 {
 {
 	struct atm_qdisc_data *p = qdisc_priv(sch);
 	struct atm_qdisc_data *p = qdisc_priv(sch);
@@ -694,6 +703,7 @@ static struct Qdisc_ops atm_qdisc_ops __read_mostly = {
 	.priv_size	= sizeof(struct atm_qdisc_data),
 	.priv_size	= sizeof(struct atm_qdisc_data),
 	.enqueue	= atm_tc_enqueue,
 	.enqueue	= atm_tc_enqueue,
 	.dequeue	= atm_tc_dequeue,
 	.dequeue	= atm_tc_dequeue,
+	.peek		= atm_tc_peek,
 	.requeue	= atm_tc_requeue,
 	.requeue	= atm_tc_requeue,
 	.drop		= atm_tc_drop,
 	.drop		= atm_tc_drop,
 	.init		= atm_tc_init,
 	.init		= atm_tc_init,

+ 1 - 0
net/sched/sch_blackhole.c

@@ -33,6 +33,7 @@ static struct Qdisc_ops blackhole_qdisc_ops __read_mostly = {
 	.priv_size	= 0,
 	.priv_size	= 0,
 	.enqueue	= blackhole_enqueue,
 	.enqueue	= blackhole_enqueue,
 	.dequeue	= blackhole_dequeue,
 	.dequeue	= blackhole_dequeue,
+	.peek		= blackhole_dequeue,
 	.owner		= THIS_MODULE,
 	.owner		= THIS_MODULE,
 };
 };
 
 

+ 10 - 0
net/sched/sch_dsmark.c

@@ -313,6 +313,15 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
 	return skb;
 	return skb;
 }
 }
 
 
+static struct sk_buff *dsmark_peek(struct Qdisc *sch)
+{
+	struct dsmark_qdisc_data *p = qdisc_priv(sch);
+
+	pr_debug("dsmark_peek(sch %p,[qdisc %p])\n", sch, p);
+
+	return p->q->ops->peek(p->q);
+}
+
 static int dsmark_requeue(struct sk_buff *skb, struct Qdisc *sch)
 static int dsmark_requeue(struct sk_buff *skb, struct Qdisc *sch)
 {
 {
 	struct dsmark_qdisc_data *p = qdisc_priv(sch);
 	struct dsmark_qdisc_data *p = qdisc_priv(sch);
@@ -496,6 +505,7 @@ static struct Qdisc_ops dsmark_qdisc_ops __read_mostly = {
 	.priv_size	=	sizeof(struct dsmark_qdisc_data),
 	.priv_size	=	sizeof(struct dsmark_qdisc_data),
 	.enqueue	=	dsmark_enqueue,
 	.enqueue	=	dsmark_enqueue,
 	.dequeue	=	dsmark_dequeue,
 	.dequeue	=	dsmark_dequeue,
+	.peek		=	dsmark_peek,
 	.requeue	=	dsmark_requeue,
 	.requeue	=	dsmark_requeue,
 	.drop		=	dsmark_drop,
 	.drop		=	dsmark_drop,
 	.init		=	dsmark_init,
 	.init		=	dsmark_init,

+ 1 - 0
net/sched/sch_gred.c

@@ -602,6 +602,7 @@ static struct Qdisc_ops gred_qdisc_ops __read_mostly = {
 	.priv_size	=	sizeof(struct gred_sched),
 	.priv_size	=	sizeof(struct gred_sched),
 	.enqueue	=	gred_enqueue,
 	.enqueue	=	gred_enqueue,
 	.dequeue	=	gred_dequeue,
 	.dequeue	=	gred_dequeue,
+	.peek		=	qdisc_peek_head,
 	.requeue	=	gred_requeue,
 	.requeue	=	gred_requeue,
 	.drop		=	gred_drop,
 	.drop		=	gred_drop,
 	.init		=	gred_init,
 	.init		=	gred_init,

+ 29 - 0
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)
 static unsigned int multiq_drop(struct Qdisc *sch)
 {
 {
 	struct multiq_sched_data *q = qdisc_priv(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),
 	.priv_size	=	sizeof(struct multiq_sched_data),
 	.enqueue	=	multiq_enqueue,
 	.enqueue	=	multiq_enqueue,
 	.dequeue	=	multiq_dequeue,
 	.dequeue	=	multiq_dequeue,
+	.peek		=	multiq_peek,
 	.requeue	=	multiq_requeue,
 	.requeue	=	multiq_requeue,
 	.drop		=	multiq_drop,
 	.drop		=	multiq_drop,
 	.init		=	multiq_init,
 	.init		=	multiq_init,

+ 1 - 0
net/sched/sch_netem.c

@@ -541,6 +541,7 @@ static struct Qdisc_ops tfifo_qdisc_ops __read_mostly = {
 	.priv_size	=	sizeof(struct fifo_sched_data),
 	.priv_size	=	sizeof(struct fifo_sched_data),
 	.enqueue	=	tfifo_enqueue,
 	.enqueue	=	tfifo_enqueue,
 	.dequeue	=	qdisc_dequeue_head,
 	.dequeue	=	qdisc_dequeue_head,
+	.peek		=	qdisc_peek_head,
 	.requeue	=	qdisc_requeue,
 	.requeue	=	qdisc_requeue,
 	.drop		=	qdisc_queue_drop,
 	.drop		=	qdisc_queue_drop,
 	.init		=	tfifo_init,
 	.init		=	tfifo_init,

+ 9 - 0
net/sched/sch_red.c

@@ -140,6 +140,14 @@ static struct sk_buff * red_dequeue(struct Qdisc* sch)
 	return skb;
 	return skb;
 }
 }
 
 
+static struct sk_buff * red_peek(struct Qdisc* sch)
+{
+	struct red_sched_data *q = qdisc_priv(sch);
+	struct Qdisc *child = q->qdisc;
+
+	return child->ops->peek(child);
+}
+
 static unsigned int red_drop(struct Qdisc* sch)
 static unsigned int red_drop(struct Qdisc* sch)
 {
 {
 	struct red_sched_data *q = qdisc_priv(sch);
 	struct red_sched_data *q = qdisc_priv(sch);
@@ -361,6 +369,7 @@ static struct Qdisc_ops red_qdisc_ops __read_mostly = {
 	.cl_ops		=	&red_class_ops,
 	.cl_ops		=	&red_class_ops,
 	.enqueue	=	red_enqueue,
 	.enqueue	=	red_enqueue,
 	.dequeue	=	red_dequeue,
 	.dequeue	=	red_dequeue,
+	.peek		=	red_peek,
 	.requeue	=	red_requeue,
 	.requeue	=	red_requeue,
 	.drop		=	red_drop,
 	.drop		=	red_drop,
 	.init		=	red_init,
 	.init		=	red_init,

+ 8 - 0
net/sched/sch_teql.c

@@ -123,6 +123,13 @@ teql_dequeue(struct Qdisc* sch)
 	return skb;
 	return skb;
 }
 }
 
 
+static struct sk_buff *
+teql_peek(struct Qdisc* sch)
+{
+	/* teql is meant to be used as root qdisc */
+	return NULL;
+}
+
 static __inline__ void
 static __inline__ void
 teql_neigh_release(struct neighbour *n)
 teql_neigh_release(struct neighbour *n)
 {
 {
@@ -433,6 +440,7 @@ static __init void teql_master_setup(struct net_device *dev)
 
 
 	ops->enqueue	=	teql_enqueue;
 	ops->enqueue	=	teql_enqueue;
 	ops->dequeue	=	teql_dequeue;
 	ops->dequeue	=	teql_dequeue;
+	ops->peek	=	teql_peek;
 	ops->requeue	=	teql_requeue;
 	ops->requeue	=	teql_requeue;
 	ops->init	=	teql_qdisc_init;
 	ops->init	=	teql_qdisc_init;
 	ops->reset	=	teql_reset;
 	ops->reset	=	teql_reset;