Commit 451b2596 authored by David S. Miller's avatar David S. Miller

Merge branch 'htb-fixes'

Maxim Mikityanskiy says:

====================
Bugfixes for HTB

The HTB offload feature introduced a few bugs in HTB. One affects the
non-offload mode, preventing attaching qdiscs to HTB classes, and the
other affects the error flow, when the netdev doesn't support the
offload, but it was requested. This short series fixes them.
====================
Acked-by: default avatarCong Wang <cong.wang@bytedance.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7a1468ba fb3a3e37
...@@ -1020,6 +1020,7 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt, ...@@ -1020,6 +1020,7 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt,
struct nlattr *tb[TCA_HTB_MAX + 1]; struct nlattr *tb[TCA_HTB_MAX + 1];
struct tc_htb_glob *gopt; struct tc_htb_glob *gopt;
unsigned int ntx; unsigned int ntx;
bool offload;
int err; int err;
qdisc_watchdog_init(&q->watchdog, sch); qdisc_watchdog_init(&q->watchdog, sch);
...@@ -1044,9 +1045,9 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt, ...@@ -1044,9 +1045,9 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt,
if (gopt->version != HTB_VER >> 16) if (gopt->version != HTB_VER >> 16)
return -EINVAL; return -EINVAL;
q->offload = nla_get_flag(tb[TCA_HTB_OFFLOAD]); offload = nla_get_flag(tb[TCA_HTB_OFFLOAD]);
if (q->offload) { if (offload) {
if (sch->parent != TC_H_ROOT) if (sch->parent != TC_H_ROOT)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -1076,7 +1077,7 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt, ...@@ -1076,7 +1077,7 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt,
q->rate2quantum = 1; q->rate2quantum = 1;
q->defcls = gopt->defcls; q->defcls = gopt->defcls;
if (!q->offload) if (!offload)
return 0; return 0;
for (ntx = 0; ntx < q->num_direct_qdiscs; ntx++) { for (ntx = 0; ntx < q->num_direct_qdiscs; ntx++) {
...@@ -1107,12 +1108,14 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt, ...@@ -1107,12 +1108,14 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt,
if (err) if (err)
goto err_free_qdiscs; goto err_free_qdiscs;
/* Defer this assignment, so that htb_destroy skips offload-related
* parts (especially calling ndo_setup_tc) on errors.
*/
q->offload = true;
return 0; return 0;
err_free_qdiscs: err_free_qdiscs:
/* TC_HTB_CREATE call failed, avoid any further calls to the driver. */
q->offload = false;
for (ntx = 0; ntx < q->num_direct_qdiscs && q->direct_qdiscs[ntx]; for (ntx = 0; ntx < q->num_direct_qdiscs && q->direct_qdiscs[ntx];
ntx++) ntx++)
qdisc_put(q->direct_qdiscs[ntx]); qdisc_put(q->direct_qdiscs[ntx]);
...@@ -1340,8 +1343,12 @@ htb_select_queue(struct Qdisc *sch, struct tcmsg *tcm) ...@@ -1340,8 +1343,12 @@ htb_select_queue(struct Qdisc *sch, struct tcmsg *tcm)
{ {
struct net_device *dev = qdisc_dev(sch); struct net_device *dev = qdisc_dev(sch);
struct tc_htb_qopt_offload offload_opt; struct tc_htb_qopt_offload offload_opt;
struct htb_sched *q = qdisc_priv(sch);
int err; int err;
if (!q->offload)
return sch->dev_queue;
offload_opt = (struct tc_htb_qopt_offload) { offload_opt = (struct tc_htb_qopt_offload) {
.command = TC_HTB_LEAF_QUERY_QUEUE, .command = TC_HTB_LEAF_QUERY_QUEUE,
.classid = TC_H_MIN(tcm->tcm_parent), .classid = TC_H_MIN(tcm->tcm_parent),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment