From 27cfca1ec98e91261b1a5355d10a8996464b63af Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 17 Mar 1998 22:05:47 +0000 Subject: Look Ma' what I found on my harddisk ... o New faster syscalls for 2.1.x, too o Upgrade to 2.1.89. Don't try to run this. It's flaky as hell. But feel free to debug ... --- net/sched/.cvsignore | 1 + net/sched/Config.in | 11 ++++++++ net/sched/sch_csz.c | 6 ++--- net/sched/sch_fifo.c | 8 +++--- net/sched/sch_generic.c | 70 ++++++++++++++++++++++++++++++++----------------- net/sched/sch_red.c | 4 +-- net/sched/sch_sfq.c | 7 +++-- net/sched/sch_tbf.c | 4 +-- 8 files changed, 72 insertions(+), 39 deletions(-) create mode 100644 net/sched/Config.in (limited to 'net/sched') diff --git a/net/sched/.cvsignore b/net/sched/.cvsignore index 4671378ae..857dd22e9 100644 --- a/net/sched/.cvsignore +++ b/net/sched/.cvsignore @@ -1 +1,2 @@ .depend +.*.flags diff --git a/net/sched/Config.in b/net/sched/Config.in new file mode 100644 index 000000000..d1287a781 --- /dev/null +++ b/net/sched/Config.in @@ -0,0 +1,11 @@ +# +# Traffic control configuration. +# +tristate 'CBQ packet scheduler' CONFIG_NET_SCH_CBQ +tristate 'CSZ packet scheduler' CONFIG_NET_SCH_CSZ +#tristate 'HFQ packet scheduler' CONFIG_NET_SCH_HFQ +tristate 'RED queueing discipline' CONFIG_NET_SCH_RED +tristate 'SFQ queueing discipline' CONFIG_NET_SCH_SFQ +tristate 'auxiliary TBF queue' CONFIG_NET_SCH_TBF +tristate 'auxiliary FIFO queue' CONFIG_NET_SCH_PFIFO +tristate 'auxiliary PRIO queue' CONFIG_NET_SCH_PRIO diff --git a/net/sched/sch_csz.c b/net/sched/sch_csz.c index dbc05d31b..5e10ac097 100644 --- a/net/sched/sch_csz.c +++ b/net/sched/sch_csz.c @@ -459,7 +459,7 @@ csz_enqueue(struct sk_buff *skb, struct Qdisc* sch) this = &q->flow[flow_id]; if (this->q.qlen >= this->max_bytes || this->L_tab == NULL) { - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); return 0; } @@ -711,12 +711,12 @@ csz_reset(struct Qdisc* sch) for (i=0; i<4; i++) while ((skb=skb_dequeue(&q->other[i])) != NULL) - kfree_skb(skb, 0); + kfree_skb(skb); for (i=0; iflow + i; while ((skb = skb_dequeue(&this->q)) != NULL) - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); this->snext = this->sprev = this->fnext = this->fprev = (struct csz_head*)this; this->start = this->finish = 0; diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c index 8134baf16..af44d4e75 100644 --- a/net/sched/sch_fifo.c +++ b/net/sched/sch_fifo.c @@ -47,7 +47,7 @@ bfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) q->qbytes += skb->len; return 0; } - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); return 1; } @@ -71,7 +71,7 @@ bfifo_reset(struct Qdisc* sch) while((skb=skb_dequeue(&sch->q)) != NULL) { q->qbytes -= skb->len; - kfree_skb(skb,FREE_WRITE); + kfree_skb(skb); } if (q->qbytes) { printk("fifo_reset: qbytes=%d\n", q->qbytes); @@ -88,7 +88,7 @@ pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) skb_queue_tail(&sch->q, skb); return 0; } - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); return 1; } @@ -104,7 +104,7 @@ pfifo_reset(struct Qdisc* sch) struct sk_buff *skb; while((skb=skb_dequeue(&sch->q))!=NULL) - kfree_skb(skb,FREE_WRITE); + kfree_skb(skb); } diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 83aa8d10e..c3399f9c1 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -34,6 +34,9 @@ struct Qdisc_head qdisc_head = { &qdisc_head }; static struct Qdisc_ops *qdisc_base = NULL; +static int default_requeue(struct sk_buff *skb, struct Qdisc* qdisc); + + /* NOTES. Every discipline has two major routines: enqueue and dequeue. @@ -75,6 +78,8 @@ int unregister_qdisc(struct Qdisc_ops *qops) break; if (!q) return -ENOENT; + if (q->requeue == NULL) + q->requeue = default_requeue; *qp = q->next; return 0; } @@ -93,7 +98,7 @@ struct Qdisc *qdisc_lookup(int handle) static int noop_enqueue(struct sk_buff *skb, struct Qdisc * qdisc) { - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); return 0; } @@ -118,6 +123,7 @@ struct Qdisc noqueue_qdisc = }; + /* 3-band FIFO queue: old style, but should be a bit faster (several CPU insns) */ static int @@ -129,11 +135,11 @@ pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc) list = ((struct sk_buff_head*)qdisc->data) + prio2band[skb->priority&7]; if (list->qlen <= skb->dev->tx_queue_len) { - skb_queue_tail(list, skb); + __skb_queue_tail(list, skb); return 1; } qdisc->dropped++; - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); return 0; } @@ -145,13 +151,25 @@ pfifo_fast_dequeue(struct Qdisc* qdisc) struct sk_buff *skb; for (prio = 0; prio < 3; prio++, list++) { - skb = skb_dequeue(list); + skb = __skb_dequeue(list); if (skb) return skb; } return NULL; } +static int +pfifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc) +{ + const static u8 prio2band[8] = { 1, 2, 2, 2, 1, 2, 0, 0 }; + struct sk_buff_head *list; + + list = ((struct sk_buff_head*)qdisc->data) + prio2band[skb->priority&7]; + + __skb_queue_head(list, skb); + return 1; +} + static void pfifo_fast_reset(struct Qdisc* qdisc) { @@ -185,9 +203,20 @@ static struct Qdisc_ops pfifo_fast_ops = pfifo_fast_dequeue, pfifo_fast_reset, NULL, - pfifo_fast_init + pfifo_fast_init, + NULL, + pfifo_fast_requeue }; +static int +default_requeue(struct sk_buff *skb, struct Qdisc* qdisc) +{ + if (net_ratelimit()) + printk(KERN_DEBUG "%s deferred output. It is buggy.\n", skb->dev->name); + kfree_skb(skb); + return 0; +} + static struct Qdisc * qdisc_alloc(struct device *dev, struct Qdisc_ops *ops, void *arg) { @@ -200,7 +229,6 @@ qdisc_alloc(struct device *dev, struct Qdisc_ops *ops, void *arg) memset(sch, 0, size); skb_queue_head_init(&sch->q); - skb_queue_head_init(&sch->failure_q); sch->ops = ops; sch->enqueue = ops->enqueue; sch->dequeue = ops->dequeue; @@ -218,7 +246,6 @@ void qdisc_reset(struct Qdisc *qdisc) start_bh_atomic(); if (ops->reset) ops->reset(qdisc); - skb_queue_purge(&qdisc->failure_q); end_bh_atomic(); } } @@ -232,7 +259,6 @@ void qdisc_destroy(struct Qdisc *qdisc) ops->reset(qdisc); if (ops->destroy) ops->destroy(qdisc); - skb_queue_purge(&qdisc->failure_q); ops->refcnt--; end_bh_atomic(); kfree(qdisc); @@ -373,23 +399,22 @@ int qdisc_restart(struct device *dev) struct Qdisc *q = dev->qdisc; struct sk_buff *skb; - skb = skb_dequeue(&q->failure_q); - if (!skb) { - skb = q->dequeue(q); - if (netdev_nit && skb) - dev_queue_xmit_nit(skb,dev); - } - if (skb) { + if ((skb = q->dequeue(q)) != NULL) { + if (netdev_nit) + dev_queue_xmit_nit(skb, dev); + if (dev->hard_start_xmit(skb, dev) == 0) { q->tx_last = jiffies; return -1; } -#if 0 - if (net_ratelimit()) - printk(KERN_DEBUG "netdevice %s defers output.\n", dev->name); -#endif - skb_queue_head(&q->failure_q, skb); - return -1; + + if (q->ops) { + q->ops->requeue(skb, q); + return -1; + } + + printk(KERN_DEBUG "%s: it is impossible!!!\n", dev->name); + kfree_skb(skb); } return q->q.qlen; } @@ -511,9 +536,6 @@ __initfunc(int pktsched_init(void)) register_qdisc(&##name##_ops); \ } - skb_queue_head_init(&noop_qdisc.failure_q); - skb_queue_head_init(&noqueue_qdisc.failure_q); - register_qdisc(&pfifo_fast_ops); #ifdef CONFIG_NET_SCH_CBQ INIT_QDISC(cbq); diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index fd3ee43ac..637288d99 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c @@ -189,7 +189,7 @@ enqueue: return 1; } drop: - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); return 0; } if (q->qave >= q->qth_max) { @@ -231,7 +231,7 @@ red_reset(struct Qdisc* sch) while((skb=skb_dequeue(&sch->q))!=NULL) { q->qbytes -= skb->len; - kfree_skb(skb,FREE_WRITE); + kfree_skb(skb); } if (q->qbytes) { printk("red_reset: qbytes=%lu\n", q->qbytes); diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 65c3906b4..7a90df655 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -174,7 +173,7 @@ static __inline__ void sfq_drop(struct sfq_sched_data *q) sfq_index x = q->dep[d].next; skb = q->qs[x].prev; __skb_unlink(skb, &q->qs[x]); - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); sfq_dec(q, x); /* sch->q.qlen--; @@ -189,7 +188,7 @@ static __inline__ void sfq_drop(struct sfq_sched_data *q) q->allot[q->next[d]] += q->quantum; skb = q->qs[d].prev; __skb_unlink(skb, &q->qs[d]); - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); sfq_dec(q, d); /* sch->q.qlen--; @@ -271,7 +270,7 @@ sfq_reset(struct Qdisc* sch) struct sk_buff *skb; while ((skb = sfq_dequeue(sch)) != NULL) - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); } diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index 9869af1d3..b4f141761 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c @@ -118,7 +118,7 @@ tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch) __skb_unlink(skb, &sch->q); q->bytes -= skb->len; - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); return 0; } @@ -187,7 +187,7 @@ tbf_reset(struct Qdisc* sch) struct sk_buff *skb; while ((skb = __skb_dequeue(&sch->q)) != NULL) - kfree_skb(skb, FREE_WRITE); + kfree_skb(skb); q->bytes = 0; PSCHED_GET_TIME(q->t_c); q->tokens = q->depth; -- cgit v1.2.3