Skip to content
Snippets Groups Projects
Commit 1f62879e authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller
Browse files

net/sched: make stab available before ops->init() call


Some qdiscs like taprio turn out to be actually pretty reliant on a well
configured stab, to not underestimate the skb transmission time (by
properly accounting for L1 overhead).

In a future change, taprio will need the stab, if configured by the
user, to be available at ops->init() time. It will become even more
important in upcoming work, when the overhead will be used for the
queueMaxSDU calculation that is passed to an offloading driver.

However, rcu_assign_pointer(sch->stab, stab) is called right after
ops->init(), making it unavailable, and I don't really see a good reason
for that.

Move it earlier, which nicely seems to simplify the error handling path
as well.

Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: default avatarKurt Kanzenbach <kurt@linutronix.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a1e6ad30
No related branches found
No related tags found
No related merge requests found
...@@ -1282,12 +1282,6 @@ static struct Qdisc *qdisc_create(struct net_device *dev, ...@@ -1282,12 +1282,6 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
if (err) if (err)
goto err_out3; goto err_out3;
if (ops->init) {
err = ops->init(sch, tca[TCA_OPTIONS], extack);
if (err != 0)
goto err_out5;
}
if (tca[TCA_STAB]) { if (tca[TCA_STAB]) {
stab = qdisc_get_stab(tca[TCA_STAB], extack); stab = qdisc_get_stab(tca[TCA_STAB], extack);
if (IS_ERR(stab)) { if (IS_ERR(stab)) {
...@@ -1296,11 +1290,18 @@ static struct Qdisc *qdisc_create(struct net_device *dev, ...@@ -1296,11 +1290,18 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
} }
rcu_assign_pointer(sch->stab, stab); rcu_assign_pointer(sch->stab, stab);
} }
if (ops->init) {
err = ops->init(sch, tca[TCA_OPTIONS], extack);
if (err != 0)
goto err_out5;
}
if (tca[TCA_RATE]) { if (tca[TCA_RATE]) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
if (sch->flags & TCQ_F_MQROOT) { if (sch->flags & TCQ_F_MQROOT) {
NL_SET_ERR_MSG(extack, "Cannot attach rate estimator to a multi-queue root qdisc"); NL_SET_ERR_MSG(extack, "Cannot attach rate estimator to a multi-queue root qdisc");
goto err_out4; goto err_out5;
} }
err = gen_new_estimator(&sch->bstats, err = gen_new_estimator(&sch->bstats,
...@@ -1311,7 +1312,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev, ...@@ -1311,7 +1312,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
tca[TCA_RATE]); tca[TCA_RATE]);
if (err) { if (err) {
NL_SET_ERR_MSG(extack, "Failed to generate new estimator"); NL_SET_ERR_MSG(extack, "Failed to generate new estimator");
goto err_out4; goto err_out5;
} }
} }
...@@ -1321,6 +1322,8 @@ static struct Qdisc *qdisc_create(struct net_device *dev, ...@@ -1321,6 +1322,8 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
return sch; return sch;
err_out5: err_out5:
qdisc_put_stab(rtnl_dereference(sch->stab));
err_out4:
/* ops->init() failed, we call ->destroy() like qdisc_create_dflt() */ /* ops->init() failed, we call ->destroy() like qdisc_create_dflt() */
if (ops->destroy) if (ops->destroy)
ops->destroy(sch); ops->destroy(sch);
...@@ -1332,16 +1335,6 @@ static struct Qdisc *qdisc_create(struct net_device *dev, ...@@ -1332,16 +1335,6 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
err_out: err_out:
*errp = err; *errp = err;
return NULL; return NULL;
err_out4:
/*
* Any broken qdiscs that would require a ops->reset() here?
* The qdisc was never in action so it shouldn't be necessary.
*/
qdisc_put_stab(rtnl_dereference(sch->stab));
if (ops->destroy)
ops->destroy(sch);
goto err_out3;
} }
static int qdisc_change(struct Qdisc *sch, struct nlattr **tca, static int qdisc_change(struct Qdisc *sch, struct nlattr **tca,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment