summaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-04-05 04:55:58 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-04-05 04:55:58 +0000
commit74a9f2e1b4d3ab45a9f72cb5b556c9f521524ab3 (patch)
tree7c4cdb103ab1b388c9852a88bd6fb1e73eba0b5c /net/sched
parentee6374c8b0d333c08061c6a97bc77090d7461225 (diff)
Merge with Linux 2.4.3.
Note that mingetty does no longer work with serial console, you have to switch to another getty like getty_ps. This commit also includes a fix for a setitimer bug which did prevent getty_ps from working on older kernels.
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/Makefile194
-rw-r--r--net/sched/cls_tcindex.c73
-rw-r--r--net/sched/sch_cbq.c8
-rw-r--r--net/sched/sch_dsmark.c8
-rw-r--r--net/sched/sch_tbf.c21
5 files changed, 92 insertions, 212 deletions
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 95707af00..164a97fe7 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -1,182 +1,34 @@
#
# Makefile for the Linux Traffic Control Unit.
#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
O_TARGET := sched.o
obj-y := sch_generic.o
-ifeq ($(CONFIG_NET_SCHED), y)
-
-obj-y += sch_api.o sch_fifo.o
-
-ifeq ($(CONFIG_NET_ESTIMATOR), y)
-obj-y += estimator.o
-endif
-
-ifeq ($(CONFIG_NET_CLS), y)
-obj-y += cls_api.o
-
-ifeq ($(CONFIG_NET_CLS_POLICE), y)
-obj-y += police.o
-endif
-
-endif
-
-ifeq ($(CONFIG_NET_SCH_INGRESS), y)
-obj-y += sch_ingress.o
-else
- ifeq ($(CONFIG_NET_SCH_INGRESS), m)
- obj-m += sch_ingress.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_SCH_CBQ), y)
-obj-y += sch_cbq.o
-else
- ifeq ($(CONFIG_NET_SCH_CBQ), m)
- obj-m += sch_cbq.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_SCH_CSZ), y)
-obj-y += sch_csz.o
-else
- ifeq ($(CONFIG_NET_SCH_CSZ), m)
- obj-m += sch_csz.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_SCH_HPFQ), y)
-obj-y += sch_hpfq.o
-else
- ifeq ($(CONFIG_NET_SCH_HPFQ), m)
- obj-m += sch_hpfq.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_SCH_HFSC), y)
-obj-y += sch_hfsc.o
-else
- ifeq ($(CONFIG_NET_SCH_HFSC), m)
- obj-m += sch_hfsc.o
- endif
-endif
-
-
-ifeq ($(CONFIG_NET_SCH_SFQ), y)
-obj-y += sch_sfq.o
-else
- ifeq ($(CONFIG_NET_SCH_SFQ), m)
- obj-m += sch_sfq.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_SCH_RED), y)
-obj-y += sch_red.o
-else
- ifeq ($(CONFIG_NET_SCH_RED), m)
- obj-m += sch_red.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_SCH_TBF), y)
-obj-y += sch_tbf.o
-else
- ifeq ($(CONFIG_NET_SCH_TBF), m)
- obj-m += sch_tbf.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_SCH_PRIO), y)
-obj-y += sch_prio.o
-else
- ifeq ($(CONFIG_NET_SCH_PRIO), m)
- obj-m += sch_prio.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_SCH_TEQL), y)
-obj-y += sch_teql.o
-else
- ifeq ($(CONFIG_NET_SCH_TEQL), m)
- obj-m += sch_teql.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_SCH_GRED), y)
-obj-y += sch_gred.o
-else
- ifeq ($(CONFIG_NET_SCH_GRED), m)
- obj-m += sch_gred.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_SCH_DSMARK), y)
-obj-y += sch_dsmark.o
-else
- ifeq ($(CONFIG_NET_SCH_DSMARK), m)
- obj-m += sch_dsmark.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_CLS_TCINDEX), y)
-obj-y += cls_tcindex.o
-else
- ifeq ($(CONFIG_NET_CLS_TCINDEX), m)
- obj-m += cls_tcindex.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_SCH_ATM), y)
-obj-y += sch_atm.o
-endif
-
-ifeq ($(CONFIG_NET_CLS_U32), y)
-obj-y += cls_u32.o
-else
- ifeq ($(CONFIG_NET_CLS_U32), m)
- obj-m += cls_u32.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_CLS_RSVP), y)
-obj-y += cls_rsvp.o
-else
- ifeq ($(CONFIG_NET_CLS_RSVP), m)
- obj-m += cls_rsvp.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_CLS_RSVP6), y)
-obj-y += cls_rsvp6.o
-else
- ifeq ($(CONFIG_NET_CLS_RSVP6), m)
- obj-m += cls_rsvp6.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_CLS_ROUTE4), y)
-obj-y += cls_route.o
-else
- ifeq ($(CONFIG_NET_CLS_ROUTE4), m)
- obj-m += cls_route.o
- endif
-endif
-
-ifeq ($(CONFIG_NET_CLS_FW), y)
-obj-y += cls_fw.o
-else
- ifeq ($(CONFIG_NET_CLS_FW), m)
- obj-m += cls_fw.o
- endif
-endif
-endif
+obj-$(CONFIG_NET_SCHED) += sch_api.o sch_fifo.o
+obj-$(CONFIG_NET_ESTIMATOR) += estimator.o
+obj-$(CONFIG_NET_CLS) += cls_api.o
+obj-$(CONFIG_NET_CLS_POLICE) += police.o
+obj-$(CONFIG_NET_SCH_INGRESS) += sch_ingress.o
+obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o
+obj-$(CONFIG_NET_SCH_CSZ) += sch_csz.o
+obj-$(CONFIG_NET_SCH_HPFQ) += sch_hpfq.o
+obj-$(CONFIG_NET_SCH_HFSC) += sch_hfsc.o
+obj-$(CONFIG_NET_SCH_SFQ) += sch_sfq.o
+obj-$(CONFIG_NET_SCH_RED) += sch_red.o
+obj-$(CONFIG_NET_SCH_TBF) += sch_tbf.o
+obj-$(CONFIG_NET_SCH_PRIO) += sch_prio.o
+obj-$(CONFIG_NET_SCH_TEQL) += sch_teql.o
+obj-$(CONFIG_NET_SCH_GRED) += sch_gred.o
+obj-$(CONFIG_NET_SCH_DSMARK) += sch_dsmark.o
+obj-$(CONFIG_NET_CLS_TCINDEX) += cls_tcindex.o
+obj-$(CONFIG_NET_SCH_ATM) += sch_atm.o
+obj-$(CONFIG_NET_CLS_U32) += cls_u32.o
+obj-$(CONFIG_NET_CLS_RSVP) += cls_rsvp.o
+obj-$(CONFIG_NET_CLS_RSVP6) += cls_rsvp6.o
+obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o
+obj-$(CONFIG_NET_CLS_FW) += cls_fw.o
include $(TOPDIR)/Rules.make
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 8ab839f8a..750eb4672 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -76,7 +76,7 @@ static struct tcindex_filter_result *lookup(struct tcindex_data *p,__u16 key)
struct tcindex_filter *f;
if (p->perfect)
- return p->perfect[key].res.classid ? p->perfect+key : NULL;
+ return p->perfect[key].res.class ? p->perfect+key : NULL;
if (!p->h)
return NULL;
for (f = p->h[key % p->hash]; f; f = f->next) {
@@ -122,8 +122,14 @@ static int tcindex_classify(struct sk_buff *skb, struct tcf_proto *tp,
static unsigned long tcindex_get(struct tcf_proto *tp, u32 handle)
{
+ struct tcindex_data *p = PRIV(tp);
+ struct tcindex_filter_result *r;
+
DPRINTK("tcindex_get(tp %p,handle 0x%08x)\n",tp,handle);
- return (unsigned long) lookup(PRIV(tp),handle);
+ if (p->perfect && handle >= p->alloc_hash)
+ return 0;
+ r = lookup(PRIV(tp),handle);
+ return r && r->res.class ? (unsigned long) r : 0;
}
@@ -164,7 +170,7 @@ static int tcindex_delete(struct tcf_proto *tp, unsigned long arg)
DPRINTK("tcindex_delete(tp %p,arg 0x%lx),p %p,f %p\n",tp,arg,p,f);
if (p->perfect) {
- if (!r->res.classid)
+ if (!r->res.class)
return -ENOENT;
} else {
int i;
@@ -212,7 +218,7 @@ static int tcindex_change(struct tcf_proto *tp,unsigned long base,u32 handle,
struct tcindex_filter *f;
struct tcindex_filter_result *r = (struct tcindex_filter_result *) *arg;
struct tcindex_filter **walk;
- int hash;
+ int hash,shift;
__u16 mask;
DPRINTK("tcindex_change(tp %p,handle 0x%08x,tca %p,arg %p),opt %p,"
@@ -237,17 +243,22 @@ static int tcindex_change(struct tcf_proto *tp,unsigned long base,u32 handle,
return -EINVAL;
mask = *(__u16 *) RTA_DATA(tb[TCA_TCINDEX_MASK-1]);
}
- if (p->perfect && hash <= mask)
+ if (!tb[TCA_TCINDEX_SHIFT-1])
+ shift = p->shift;
+ else {
+ if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT-1]) < sizeof(__u16))
+ return -EINVAL;
+ shift = *(int *) RTA_DATA(tb[TCA_TCINDEX_SHIFT-1]);
+ }
+ if (p->perfect && hash <= (mask >> shift))
return -EBUSY;
- if ((p->perfect || p->h) && hash > p->alloc_hash)
+ if (p->perfect && hash > p->alloc_hash)
+ return -EBUSY;
+ if (p->h && hash != p->alloc_hash)
return -EBUSY;
p->hash = hash;
p->mask = mask;
- if (tb[TCA_TCINDEX_SHIFT-1]) {
- if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT-1]) < sizeof(__u16))
- return -EINVAL;
- p->shift = *(int *) RTA_DATA(tb[TCA_TCINDEX_SHIFT-1]);
- }
+ p->shift = shift;
if (tb[TCA_TCINDEX_FALL_THROUGH-1]) {
if (RTA_PAYLOAD(tb[TCA_TCINDEX_FALL_THROUGH-1]) < sizeof(int))
return -EINVAL;
@@ -258,9 +269,9 @@ static int tcindex_change(struct tcf_proto *tp,unsigned long base,u32 handle,
tb[TCA_TCINDEX_POLICE-1]);
if (!tb[TCA_TCINDEX_CLASSID-1] && !tb[TCA_TCINDEX_POLICE-1])
return 0;
- if (!p->hash) {
- if (p->mask < PERFECT_HASH_THRESHOLD) {
- p->hash = p->mask+1;
+ if (!hash) {
+ if ((mask >> shift) < PERFECT_HASH_THRESHOLD) {
+ p->hash = (mask >> shift)+1;
} else {
p->hash = DEFAULT_HASH_SIZE;
}
@@ -268,7 +279,7 @@ static int tcindex_change(struct tcf_proto *tp,unsigned long base,u32 handle,
if (!p->perfect && !p->h) {
p->alloc_hash = p->hash;
DPRINTK("hash %d mask %d\n",p->hash,p->mask);
- if (p->hash > p->mask) {
+ if (p->hash > (mask >> shift)) {
p->perfect = kmalloc(p->hash*
sizeof(struct tcindex_filter_result),GFP_KERNEL);
if (!p->perfect)
@@ -283,7 +294,15 @@ static int tcindex_change(struct tcf_proto *tp,unsigned long base,u32 handle,
memset(p->h, 0, p->hash*sizeof(struct tcindex_filter *));
}
}
- if (handle > p->mask)
+ /*
+ * Note: this could be as restrictive as
+ * if (handle & ~(mask >> shift))
+ * but then, we'd fail handles that may become valid after some
+ * future mask change. While this is extremely unlikely to ever
+ * matter, the check below is safer (and also more
+ * backwards-compatible).
+ */
+ if (p->perfect && handle >= p->alloc_hash)
return -EINVAL;
if (p->perfect) {
r = p->perfect+handle;
@@ -308,17 +327,16 @@ static int tcindex_change(struct tcf_proto *tp,unsigned long base,u32 handle,
}
}
#ifdef CONFIG_NET_CLS_POLICE
- if (!tb[TCA_TCINDEX_POLICE-1]) {
- r->police = NULL;
- } else {
- struct tcf_police *police =
- tcf_police_locate(tb[TCA_TCINDEX_POLICE-1],NULL);
+ {
+ struct tcf_police *police;
- tcf_tree_lock(tp);
+ police = tb[TCA_TCINDEX_POLICE-1] ?
+ tcf_police_locate(tb[TCA_TCINDEX_POLICE-1],NULL) : NULL;
+ tcf_tree_lock(tp);
police = xchg(&r->police,police);
- tcf_tree_unlock(tp);
+ tcf_tree_unlock(tp);
tcf_police_release(police);
- }
+ }
#endif
if (r != &new_filter_result)
return 0;
@@ -339,13 +357,13 @@ static int tcindex_change(struct tcf_proto *tp,unsigned long base,u32 handle,
static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker)
{
struct tcindex_data *p = PRIV(tp);
- struct tcindex_filter *f;
+ struct tcindex_filter *f,*next;
int i;
DPRINTK("tcindex_walk(tp %p,walker %p),p %p\n",tp,walker,p);
if (p->perfect) {
for (i = 0; i < p->hash; i++) {
- if (!p->perfect[i].res.classid)
+ if (!p->perfect[i].res.class)
continue;
if (walker->count >= walker->skip) {
if (walker->fn(tp,
@@ -361,7 +379,8 @@ static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker)
if (!p->h)
return;
for (i = 0; i < p->hash; i++) {
- for (f = p->h[i]; f; f = f->next) {
+ for (f = p->h[i]; f; f = next) {
+ next = f->next;
if (walker->count >= walker->skip) {
if (walker->fn(tp,(unsigned long) &f->result,
walker) < 0) {
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index dc9f11aa7..a0c2d7585 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -506,7 +506,7 @@ static void cbq_ovl_classic(struct cbq_class *cl)
}
}
- q->wd_expires = delay;
+ q->wd_expires = base_delay;
}
}
@@ -1740,9 +1740,13 @@ cbq_destroy(struct Qdisc* sch)
}
for (h = 0; h < 16; h++) {
- for (cl = q->classes[h]; cl; cl = cl->next)
+ struct cbq_class *next;
+
+ for (cl = q->classes[h]; cl; cl = next) {
+ next = cl->next;
if (cl != &q->link)
cbq_destroy_class(cl);
+ }
}
qdisc_put_rtab(q->link.R_tab);
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index d30d08896..184ca0ac8 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -84,7 +84,9 @@ static int dsmark_graft(struct Qdisc *sch,unsigned long arg,
static struct Qdisc *dsmark_leaf(struct Qdisc *sch, unsigned long arg)
{
- return NULL;
+ struct dsmark_qdisc_data *p = PRIV(sch);
+
+ return p->q;
}
@@ -187,7 +189,7 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
struct dsmark_qdisc_data *p = PRIV(sch);
struct tcf_result res;
int result;
- int ret;
+ int ret = NET_XMIT_POLICED;
D2PRINTK("dsmark_enqueue(skb %p,sch %p,[qdisc %p])\n",skb,sch,p);
if (p->set_tc_index) {
@@ -237,7 +239,7 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
((ret = p->q->enqueue(skb,p->q)) != 0)) {
sch->stats.drops++;
- return 0;
+ return ret;
}
sch->stats.bytes += skb->len;
sch->stats.packets++;
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 061ef312a..7b5248e74 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -66,7 +66,7 @@
N(t+delta) = min{B/R, N(t) + delta}
If the first packet in queue has length S, it may be
- transmited only at the time t_* when S/R <= N(t_*),
+ transmitted only at the time t_* when S/R <= N(t_*),
and in this case N(t) jumps:
N(t_* + 0) = N(t_* - 0) - S/R.
@@ -276,7 +276,7 @@ static int tbf_change(struct Qdisc* sch, struct rtattr *opt)
struct tc_tbf_qopt *qopt;
struct qdisc_rate_table *rtab = NULL;
struct qdisc_rate_table *ptab = NULL;
- int max_size;
+ int max_size,n;
if (rtattr_parse(tb, TCA_TBF_PTAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
tb[TCA_TBF_PARMS-1] == NULL ||
@@ -295,15 +295,18 @@ static int tbf_change(struct Qdisc* sch, struct rtattr *opt)
goto done;
}
- max_size = psched_mtu(sch->dev);
+ for (n = 0; n < 256; n++)
+ if (rtab->data[n] > qopt->buffer) break;
+ max_size = (n << qopt->rate.cell_log)-1;
if (ptab) {
- int n = max_size>>qopt->peakrate.cell_log;
- while (n>0 && ptab->data[n-1] > qopt->mtu) {
- max_size -= (1<<qopt->peakrate.cell_log);
- n--;
- }
+ int size;
+
+ for (n = 0; n < 256; n++)
+ if (ptab->data[n] > qopt->mtu) break;
+ size = (n << qopt->peakrate.cell_log)-1;
+ if (size < max_size) max_size = size;
}
- if (rtab->data[max_size>>qopt->rate.cell_log] > qopt->buffer)
+ if (max_size < 0)
goto done;
sch_tree_lock(sch);