Commit d1fca67f authored by David S. Miller's avatar David S. Miller

Merge branch 'net-sched-Make-qdisc-offload-uapi-uniform'

Yuval Mintz says:

====================
net: sched: Make qdisc offload uapi uniform

Several qdiscs can already be offloaded to hardware, but there's an
inconsistecy in regard to the uapi through which they indicate such
an offload is taking place - indication is passed to the user via
TCA_OPTIONS where each qdisc retains private logic for setting it.

The recent addition of offloading to RED in
602f3baf ("net_sch: red: Add offload ability to RED qdisc") caused
the addition of yet another uapi field for this purpose -
TC_RED_OFFLOADED.

For clarity and prevention of bloat in the uapi we want to eliminate
said added uapi, replacing it with a common mechanism that can be used
to reflect offload status of the various qdiscs.

The first patch introduces TCA_HW_OFFLOAD as the generic message meant
for this purpose. The second changes the current RED implementation into
setting the internal bits necessary for passing it, and the third removes
TC_RED_OFFLOADED as its no longer needed.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0a060697 4a98795b
...@@ -71,6 +71,7 @@ struct Qdisc { ...@@ -71,6 +71,7 @@ struct Qdisc {
* qdisc_tree_decrease_qlen() should stop. * qdisc_tree_decrease_qlen() should stop.
*/ */
#define TCQ_F_INVISIBLE 0x80 /* invisible by default in dump */ #define TCQ_F_INVISIBLE 0x80 /* invisible by default in dump */
#define TCQ_F_OFFLOADED 0x200 /* qdisc is offloaded to HW */
u32 limit; u32 limit;
const struct Qdisc_ops *ops; const struct Qdisc_ops *ops;
struct qdisc_size_table __rcu *stab; struct qdisc_size_table __rcu *stab;
......
...@@ -256,7 +256,6 @@ struct tc_red_qopt { ...@@ -256,7 +256,6 @@ struct tc_red_qopt {
#define TC_RED_ECN 1 #define TC_RED_ECN 1
#define TC_RED_HARDDROP 2 #define TC_RED_HARDDROP 2
#define TC_RED_ADAPTATIVE 4 #define TC_RED_ADAPTATIVE 4
#define TC_RED_OFFLOADED 8
}; };
struct tc_red_xstats { struct tc_red_xstats {
......
...@@ -557,6 +557,7 @@ enum { ...@@ -557,6 +557,7 @@ enum {
TCA_PAD, TCA_PAD,
TCA_DUMP_INVISIBLE, TCA_DUMP_INVISIBLE,
TCA_CHAIN, TCA_CHAIN,
TCA_HW_OFFLOAD,
__TCA_MAX __TCA_MAX
}; };
......
...@@ -795,6 +795,8 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, ...@@ -795,6 +795,8 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
tcm->tcm_info = refcount_read(&q->refcnt); tcm->tcm_info = refcount_read(&q->refcnt);
if (nla_put_string(skb, TCA_KIND, q->ops->id)) if (nla_put_string(skb, TCA_KIND, q->ops->id))
goto nla_put_failure; goto nla_put_failure;
if (nla_put_u8(skb, TCA_HW_OFFLOAD, !!(q->flags & TCQ_F_OFFLOADED)))
goto nla_put_failure;
if (q->ops->dump && q->ops->dump(q, skb) < 0) if (q->ops->dump && q->ops->dump(q, skb) < 0)
goto nla_put_failure; goto nla_put_failure;
qlen = q->q.qlen; qlen = q->q.qlen;
......
...@@ -157,6 +157,7 @@ static int red_offload(struct Qdisc *sch, bool enable) ...@@ -157,6 +157,7 @@ static int red_offload(struct Qdisc *sch, bool enable)
.handle = sch->handle, .handle = sch->handle,
.parent = sch->parent, .parent = sch->parent,
}; };
int err;
if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc) if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -171,7 +172,14 @@ static int red_offload(struct Qdisc *sch, bool enable) ...@@ -171,7 +172,14 @@ static int red_offload(struct Qdisc *sch, bool enable)
opt.command = TC_RED_DESTROY; opt.command = TC_RED_DESTROY;
} }
return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, &opt); err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, &opt);
if (!err && enable)
sch->flags |= TCQ_F_OFFLOADED;
else
sch->flags &= ~TCQ_F_OFFLOADED;
return err;
} }
static void red_destroy(struct Qdisc *sch) static void red_destroy(struct Qdisc *sch)
...@@ -274,7 +282,7 @@ static int red_init(struct Qdisc *sch, struct nlattr *opt) ...@@ -274,7 +282,7 @@ static int red_init(struct Qdisc *sch, struct nlattr *opt)
return red_change(sch, opt); return red_change(sch, opt);
} }
static int red_dump_offload(struct Qdisc *sch, struct tc_red_qopt *opt) static int red_dump_offload_stats(struct Qdisc *sch, struct tc_red_qopt *opt)
{ {
struct net_device *dev = qdisc_dev(sch); struct net_device *dev = qdisc_dev(sch);
struct tc_red_qopt_offload hw_stats = { struct tc_red_qopt_offload hw_stats = {
...@@ -286,21 +294,12 @@ static int red_dump_offload(struct Qdisc *sch, struct tc_red_qopt *opt) ...@@ -286,21 +294,12 @@ static int red_dump_offload(struct Qdisc *sch, struct tc_red_qopt *opt)
.stats.qstats = &sch->qstats, .stats.qstats = &sch->qstats,
}, },
}; };
int err;
opt->flags &= ~TC_RED_OFFLOADED; if (!(sch->flags & TCQ_F_OFFLOADED))
if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
return 0;
err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED,
&hw_stats);
if (err == -EOPNOTSUPP)
return 0; return 0;
if (!err) return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED,
opt->flags |= TC_RED_OFFLOADED; &hw_stats);
return err;
} }
static int red_dump(struct Qdisc *sch, struct sk_buff *skb) static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
...@@ -319,7 +318,7 @@ static int red_dump(struct Qdisc *sch, struct sk_buff *skb) ...@@ -319,7 +318,7 @@ static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
int err; int err;
sch->qstats.backlog = q->qdisc->qstats.backlog; sch->qstats.backlog = q->qdisc->qstats.backlog;
err = red_dump_offload(sch, &opt); err = red_dump_offload_stats(sch, &opt);
if (err) if (err)
goto nla_put_failure; goto nla_put_failure;
...@@ -347,7 +346,7 @@ static int red_dump_stats(struct Qdisc *sch, struct gnet_dump *d) ...@@ -347,7 +346,7 @@ static int red_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
.marked = q->stats.prob_mark + q->stats.forced_mark, .marked = q->stats.prob_mark + q->stats.forced_mark,
}; };
if (tc_can_offload(dev) && dev->netdev_ops->ndo_setup_tc) { if (sch->flags & TCQ_F_OFFLOADED) {
struct red_stats hw_stats = {0}; struct red_stats hw_stats = {0};
struct tc_red_qopt_offload hw_stats_request = { struct tc_red_qopt_offload hw_stats_request = {
.command = TC_RED_XSTATS, .command = TC_RED_XSTATS,
......
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