Skip to content

Commit 1f62879

Browse files
vladimirolteandavem330
authored andcommitted
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: Vladimir Oltean <[email protected]> Reviewed-by: Kurt Kanzenbach <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a1e6ad3 commit 1f62879

File tree

1 file changed

+11
-18
lines changed

1 file changed

+11
-18
lines changed

net/sched/sch_api.c

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,12 +1282,6 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
12821282
if (err)
12831283
goto err_out3;
12841284

1285-
if (ops->init) {
1286-
err = ops->init(sch, tca[TCA_OPTIONS], extack);
1287-
if (err != 0)
1288-
goto err_out5;
1289-
}
1290-
12911285
if (tca[TCA_STAB]) {
12921286
stab = qdisc_get_stab(tca[TCA_STAB], extack);
12931287
if (IS_ERR(stab)) {
@@ -1296,11 +1290,18 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
12961290
}
12971291
rcu_assign_pointer(sch->stab, stab);
12981292
}
1293+
1294+
if (ops->init) {
1295+
err = ops->init(sch, tca[TCA_OPTIONS], extack);
1296+
if (err != 0)
1297+
goto err_out5;
1298+
}
1299+
12991300
if (tca[TCA_RATE]) {
13001301
err = -EOPNOTSUPP;
13011302
if (sch->flags & TCQ_F_MQROOT) {
13021303
NL_SET_ERR_MSG(extack, "Cannot attach rate estimator to a multi-queue root qdisc");
1303-
goto err_out4;
1304+
goto err_out5;
13041305
}
13051306

13061307
err = gen_new_estimator(&sch->bstats,
@@ -1311,7 +1312,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
13111312
tca[TCA_RATE]);
13121313
if (err) {
13131314
NL_SET_ERR_MSG(extack, "Failed to generate new estimator");
1314-
goto err_out4;
1315+
goto err_out5;
13151316
}
13161317
}
13171318

@@ -1321,6 +1322,8 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
13211322
return sch;
13221323

13231324
err_out5:
1325+
qdisc_put_stab(rtnl_dereference(sch->stab));
1326+
err_out4:
13241327
/* ops->init() failed, we call ->destroy() like qdisc_create_dflt() */
13251328
if (ops->destroy)
13261329
ops->destroy(sch);
@@ -1332,16 +1335,6 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
13321335
err_out:
13331336
*errp = err;
13341337
return NULL;
1335-
1336-
err_out4:
1337-
/*
1338-
* Any broken qdiscs that would require a ops->reset() here?
1339-
* The qdisc was never in action so it shouldn't be necessary.
1340-
*/
1341-
qdisc_put_stab(rtnl_dereference(sch->stab));
1342-
if (ops->destroy)
1343-
ops->destroy(sch);
1344-
goto err_out3;
13451338
}
13461339

13471340
static int qdisc_change(struct Qdisc *sch, struct nlattr **tca,

0 commit comments

Comments
 (0)