mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-27 21:03:32 +00:00
[NET_SCHED]: Set parent classid in default qdiscs
Set parent classids in default qdiscs to allow walking up the tree from outside the qdiscs. This is needed by the next patch. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
814a175e7b
commit
9f9afec482
11 changed files with 40 additions and 24 deletions
|
@ -174,7 +174,7 @@ extern void qdisc_reset(struct Qdisc *qdisc);
|
||||||
extern void qdisc_destroy(struct Qdisc *qdisc);
|
extern void qdisc_destroy(struct Qdisc *qdisc);
|
||||||
extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops);
|
extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops);
|
||||||
extern struct Qdisc *qdisc_create_dflt(struct net_device *dev,
|
extern struct Qdisc *qdisc_create_dflt(struct net_device *dev,
|
||||||
struct Qdisc_ops *ops);
|
struct Qdisc_ops *ops, u32 parentid);
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
tcf_destroy(struct tcf_proto *tp)
|
tcf_destroy(struct tcf_proto *tp)
|
||||||
|
|
|
@ -316,7 +316,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
|
||||||
}
|
}
|
||||||
memset(flow,0,sizeof(*flow));
|
memset(flow,0,sizeof(*flow));
|
||||||
flow->filter_list = NULL;
|
flow->filter_list = NULL;
|
||||||
if (!(flow->q = qdisc_create_dflt(sch->dev,&pfifo_qdisc_ops)))
|
if (!(flow->q = qdisc_create_dflt(sch->dev,&pfifo_qdisc_ops,classid)))
|
||||||
flow->q = &noop_qdisc;
|
flow->q = &noop_qdisc;
|
||||||
DPRINTK("atm_tc_change: qdisc %p\n",flow->q);
|
DPRINTK("atm_tc_change: qdisc %p\n",flow->q);
|
||||||
flow->sock = sock;
|
flow->sock = sock;
|
||||||
|
@ -576,7 +576,8 @@ static int atm_tc_init(struct Qdisc *sch,struct rtattr *opt)
|
||||||
|
|
||||||
DPRINTK("atm_tc_init(sch %p,[qdisc %p],opt %p)\n",sch,p,opt);
|
DPRINTK("atm_tc_init(sch %p,[qdisc %p],opt %p)\n",sch,p,opt);
|
||||||
p->flows = &p->link;
|
p->flows = &p->link;
|
||||||
if(!(p->link.q = qdisc_create_dflt(sch->dev,&pfifo_qdisc_ops)))
|
if(!(p->link.q = qdisc_create_dflt(sch->dev,&pfifo_qdisc_ops,
|
||||||
|
sch->handle)))
|
||||||
p->link.q = &noop_qdisc;
|
p->link.q = &noop_qdisc;
|
||||||
DPRINTK("atm_tc_init: link (%p) qdisc %p\n",&p->link,p->link.q);
|
DPRINTK("atm_tc_init: link (%p) qdisc %p\n",&p->link,p->link.q);
|
||||||
p->link.filter_list = NULL;
|
p->link.filter_list = NULL;
|
||||||
|
|
|
@ -1429,7 +1429,8 @@ static int cbq_init(struct Qdisc *sch, struct rtattr *opt)
|
||||||
q->link.sibling = &q->link;
|
q->link.sibling = &q->link;
|
||||||
q->link.classid = sch->handle;
|
q->link.classid = sch->handle;
|
||||||
q->link.qdisc = sch;
|
q->link.qdisc = sch;
|
||||||
if (!(q->link.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops)))
|
if (!(q->link.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
|
||||||
|
sch->handle)))
|
||||||
q->link.q = &noop_qdisc;
|
q->link.q = &noop_qdisc;
|
||||||
|
|
||||||
q->link.priority = TC_CBQ_MAXPRIO-1;
|
q->link.priority = TC_CBQ_MAXPRIO-1;
|
||||||
|
@ -1674,7 +1675,8 @@ static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
|
||||||
|
|
||||||
if (cl) {
|
if (cl) {
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
if ((new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops)) == NULL)
|
if ((new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
|
||||||
|
cl->classid)) == NULL)
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
} else {
|
} else {
|
||||||
#ifdef CONFIG_NET_CLS_POLICE
|
#ifdef CONFIG_NET_CLS_POLICE
|
||||||
|
@ -1932,7 +1934,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
|
||||||
cl->R_tab = rtab;
|
cl->R_tab = rtab;
|
||||||
rtab = NULL;
|
rtab = NULL;
|
||||||
cl->refcnt = 1;
|
cl->refcnt = 1;
|
||||||
if (!(cl->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops)))
|
if (!(cl->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid)))
|
||||||
cl->q = &noop_qdisc;
|
cl->q = &noop_qdisc;
|
||||||
cl->classid = classid;
|
cl->classid = classid;
|
||||||
cl->tparent = parent;
|
cl->tparent = parent;
|
||||||
|
|
|
@ -88,7 +88,8 @@ static int dsmark_graft(struct Qdisc *sch, unsigned long arg,
|
||||||
sch, p, new, old);
|
sch, p, new, old);
|
||||||
|
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
|
new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
|
||||||
|
sch->handle);
|
||||||
if (new == NULL)
|
if (new == NULL)
|
||||||
new = &noop_qdisc;
|
new = &noop_qdisc;
|
||||||
}
|
}
|
||||||
|
@ -387,7 +388,7 @@ static int dsmark_init(struct Qdisc *sch, struct rtattr *opt)
|
||||||
p->default_index = default_index;
|
p->default_index = default_index;
|
||||||
p->set_tc_index = RTA_GET_FLAG(tb[TCA_DSMARK_SET_TC_INDEX-1]);
|
p->set_tc_index = RTA_GET_FLAG(tb[TCA_DSMARK_SET_TC_INDEX-1]);
|
||||||
|
|
||||||
p->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
|
p->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, sch->handle);
|
||||||
if (p->q == NULL)
|
if (p->q == NULL)
|
||||||
p->q = &noop_qdisc;
|
p->q = &noop_qdisc;
|
||||||
|
|
||||||
|
|
|
@ -450,13 +450,15 @@ struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops)
|
||||||
return ERR_PTR(-err);
|
return ERR_PTR(-err);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops)
|
struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops,
|
||||||
|
unsigned int parentid)
|
||||||
{
|
{
|
||||||
struct Qdisc *sch;
|
struct Qdisc *sch;
|
||||||
|
|
||||||
sch = qdisc_alloc(dev, ops);
|
sch = qdisc_alloc(dev, ops);
|
||||||
if (IS_ERR(sch))
|
if (IS_ERR(sch))
|
||||||
goto errout;
|
goto errout;
|
||||||
|
sch->parent = parentid;
|
||||||
|
|
||||||
if (!ops->init || ops->init(sch, NULL) == 0)
|
if (!ops->init || ops->init(sch, NULL) == 0)
|
||||||
return sch;
|
return sch;
|
||||||
|
@ -520,7 +522,8 @@ void dev_activate(struct net_device *dev)
|
||||||
if (dev->qdisc_sleeping == &noop_qdisc) {
|
if (dev->qdisc_sleeping == &noop_qdisc) {
|
||||||
struct Qdisc *qdisc;
|
struct Qdisc *qdisc;
|
||||||
if (dev->tx_queue_len) {
|
if (dev->tx_queue_len) {
|
||||||
qdisc = qdisc_create_dflt(dev, &pfifo_fast_ops);
|
qdisc = qdisc_create_dflt(dev, &pfifo_fast_ops,
|
||||||
|
TC_H_ROOT);
|
||||||
if (qdisc == NULL) {
|
if (qdisc == NULL) {
|
||||||
printk(KERN_INFO "%s: activation failed\n", dev->name);
|
printk(KERN_INFO "%s: activation failed\n", dev->name);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1138,7 +1138,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
||||||
cl->classid = classid;
|
cl->classid = classid;
|
||||||
cl->sched = q;
|
cl->sched = q;
|
||||||
cl->cl_parent = parent;
|
cl->cl_parent = parent;
|
||||||
cl->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
|
cl->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid);
|
||||||
if (cl->qdisc == NULL)
|
if (cl->qdisc == NULL)
|
||||||
cl->qdisc = &noop_qdisc;
|
cl->qdisc = &noop_qdisc;
|
||||||
cl->stats_lock = &sch->dev->queue_lock;
|
cl->stats_lock = &sch->dev->queue_lock;
|
||||||
|
@ -1271,7 +1271,8 @@ hfsc_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
|
||||||
if (cl->level > 0)
|
if (cl->level > 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
|
new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
|
||||||
|
cl->classid);
|
||||||
if (new == NULL)
|
if (new == NULL)
|
||||||
new = &noop_qdisc;
|
new = &noop_qdisc;
|
||||||
}
|
}
|
||||||
|
@ -1514,7 +1515,8 @@ hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt)
|
||||||
q->root.refcnt = 1;
|
q->root.refcnt = 1;
|
||||||
q->root.classid = sch->handle;
|
q->root.classid = sch->handle;
|
||||||
q->root.sched = q;
|
q->root.sched = q;
|
||||||
q->root.qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
|
q->root.qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
|
||||||
|
sch->handle);
|
||||||
if (q->root.qdisc == NULL)
|
if (q->root.qdisc == NULL)
|
||||||
q->root.qdisc = &noop_qdisc;
|
q->root.qdisc = &noop_qdisc;
|
||||||
q->root.stats_lock = &sch->dev->queue_lock;
|
q->root.stats_lock = &sch->dev->queue_lock;
|
||||||
|
|
|
@ -1223,8 +1223,9 @@ static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
|
||||||
struct htb_class *cl = (struct htb_class *)arg;
|
struct htb_class *cl = (struct htb_class *)arg;
|
||||||
|
|
||||||
if (cl && !cl->level) {
|
if (cl && !cl->level) {
|
||||||
if (new == NULL && (new = qdisc_create_dflt(sch->dev,
|
if (new == NULL &&
|
||||||
&pfifo_qdisc_ops))
|
(new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
|
||||||
|
cl->classid))
|
||||||
== NULL)
|
== NULL)
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
sch_tree_lock(sch);
|
sch_tree_lock(sch);
|
||||||
|
@ -1415,7 +1416,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
|
||||||
/* create leaf qdisc early because it uses kmalloc(GFP_KERNEL)
|
/* create leaf qdisc early because it uses kmalloc(GFP_KERNEL)
|
||||||
so that can't be used inside of sch_tree_lock
|
so that can't be used inside of sch_tree_lock
|
||||||
-- thanks to Karlis Peisenieks */
|
-- thanks to Karlis Peisenieks */
|
||||||
new_q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
|
new_q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid);
|
||||||
sch_tree_lock(sch);
|
sch_tree_lock(sch);
|
||||||
if (parent && !parent->level) {
|
if (parent && !parent->level) {
|
||||||
/* turn parent into inner node */
|
/* turn parent into inner node */
|
||||||
|
|
|
@ -574,7 +574,8 @@ static int netem_init(struct Qdisc *sch, struct rtattr *opt)
|
||||||
q->timer.function = netem_watchdog;
|
q->timer.function = netem_watchdog;
|
||||||
q->timer.data = (unsigned long) sch;
|
q->timer.data = (unsigned long) sch;
|
||||||
|
|
||||||
q->qdisc = qdisc_create_dflt(sch->dev, &tfifo_qdisc_ops);
|
q->qdisc = qdisc_create_dflt(sch->dev, &tfifo_qdisc_ops,
|
||||||
|
TC_H_MAKE(sch->handle, 1));
|
||||||
if (!q->qdisc) {
|
if (!q->qdisc) {
|
||||||
pr_debug("netem: qdisc create failed\n");
|
pr_debug("netem: qdisc create failed\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
@ -230,7 +230,8 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt)
|
||||||
for (i=0; i<q->bands; i++) {
|
for (i=0; i<q->bands; i++) {
|
||||||
if (q->queues[i] == &noop_qdisc) {
|
if (q->queues[i] == &noop_qdisc) {
|
||||||
struct Qdisc *child;
|
struct Qdisc *child;
|
||||||
child = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
|
child = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
|
||||||
|
TC_H_MAKE(sch->handle, i + 1));
|
||||||
if (child) {
|
if (child) {
|
||||||
sch_tree_lock(sch);
|
sch_tree_lock(sch);
|
||||||
child = xchg(&q->queues[i], child);
|
child = xchg(&q->queues[i], child);
|
||||||
|
|
|
@ -175,12 +175,14 @@ static void red_destroy(struct Qdisc *sch)
|
||||||
qdisc_destroy(q->qdisc);
|
qdisc_destroy(q->qdisc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct Qdisc *red_create_dflt(struct net_device *dev, u32 limit)
|
static struct Qdisc *red_create_dflt(struct Qdisc *sch, u32 limit)
|
||||||
{
|
{
|
||||||
struct Qdisc *q = qdisc_create_dflt(dev, &bfifo_qdisc_ops);
|
struct Qdisc *q;
|
||||||
struct rtattr *rta;
|
struct rtattr *rta;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
q = qdisc_create_dflt(sch->dev, &bfifo_qdisc_ops,
|
||||||
|
TC_H_MAKE(sch->handle, 1));
|
||||||
if (q) {
|
if (q) {
|
||||||
rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)),
|
rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
@ -219,7 +221,7 @@ static int red_change(struct Qdisc *sch, struct rtattr *opt)
|
||||||
ctl = RTA_DATA(tb[TCA_RED_PARMS-1]);
|
ctl = RTA_DATA(tb[TCA_RED_PARMS-1]);
|
||||||
|
|
||||||
if (ctl->limit > 0) {
|
if (ctl->limit > 0) {
|
||||||
child = red_create_dflt(sch->dev, ctl->limit);
|
child = red_create_dflt(sch, ctl->limit);
|
||||||
if (child == NULL)
|
if (child == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,12 +273,14 @@ static void tbf_reset(struct Qdisc* sch)
|
||||||
del_timer(&q->wd_timer);
|
del_timer(&q->wd_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct Qdisc *tbf_create_dflt_qdisc(struct net_device *dev, u32 limit)
|
static struct Qdisc *tbf_create_dflt_qdisc(struct Qdisc *sch, u32 limit)
|
||||||
{
|
{
|
||||||
struct Qdisc *q = qdisc_create_dflt(dev, &bfifo_qdisc_ops);
|
struct Qdisc *q;
|
||||||
struct rtattr *rta;
|
struct rtattr *rta;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
q = qdisc_create_dflt(sch->dev, &bfifo_qdisc_ops,
|
||||||
|
TC_H_MAKE(sch->handle, 1));
|
||||||
if (q) {
|
if (q) {
|
||||||
rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
|
rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
|
||||||
if (rta) {
|
if (rta) {
|
||||||
|
@ -341,7 +343,7 @@ static int tbf_change(struct Qdisc* sch, struct rtattr *opt)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (qopt->limit > 0) {
|
if (qopt->limit > 0) {
|
||||||
if ((child = tbf_create_dflt_qdisc(sch->dev, qopt->limit)) == NULL)
|
if ((child = tbf_create_dflt_qdisc(sch, qopt->limit)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue