diff options
author | Jakub Kicinski <jakub.kicinski@netronome.com> | 2018-05-25 21:53:35 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-05-29 09:49:16 -0400 |
commit | f971b132300fb0df63a8de631947adc74a7b3db1 (patch) | |
tree | 9c0056ab9b9896ee5ffc0f806b9286281a6f6b27 | |
parent | 2ef3c253f15a7784ce541417d5663d2d1e751231 (diff) | |
download | linux-stable-f971b132300fb0df63a8de631947adc74a7b3db1.tar.gz linux-stable-f971b132300fb0df63a8de631947adc74a7b3db1.tar.bz2 linux-stable-f971b132300fb0df63a8de631947adc74a7b3db1.zip |
net: sched: mq: add simple offload notification
mq offload is trivial, we just need to let the device know
that the root qdisc is mq. Alternative approach would be
to export qdisc_lookup() and make drivers check the root
type themselves, but notification via ndo_setup_tc is more
in line with other qdiscs.
Note that mq doesn't hold any stats on it's own, it just
adds up stats of its children.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/netdevice.h | 1 | ||||
-rw-r--r-- | include/net/pkt_cls.h | 10 | ||||
-rw-r--r-- | net/sched/sch_mq.c | 19 |
3 files changed, 30 insertions, 0 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index f45b1a4e37ab..6b863ed3174a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -791,6 +791,7 @@ enum tc_setup_type { TC_SETUP_QDISC_CBS, TC_SETUP_QDISC_RED, TC_SETUP_QDISC_PRIO, + TC_SETUP_QDISC_MQ, }; /* These structures hold the attributes of bpf state that are being passed diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index f3ec43725724..942f839dbca4 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -778,6 +778,16 @@ struct tc_qopt_offload_stats { struct gnet_stats_queue *qstats; }; +enum tc_mq_command { + TC_MQ_CREATE, + TC_MQ_DESTROY, +}; + +struct tc_mq_qopt_offload { + enum tc_mq_command command; + u32 handle; +}; + enum tc_red_command { TC_RED_REPLACE, TC_RED_DESTROY, diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c index f062a18e9162..6ccf6daa2503 100644 --- a/net/sched/sch_mq.c +++ b/net/sched/sch_mq.c @@ -16,6 +16,7 @@ #include <linux/errno.h> #include <linux/skbuff.h> #include <net/netlink.h> +#include <net/pkt_cls.h> #include <net/pkt_sched.h> #include <net/sch_generic.h> @@ -23,12 +24,28 @@ struct mq_sched { struct Qdisc **qdiscs; }; +static int mq_offload(struct Qdisc *sch, enum tc_mq_command cmd) +{ + struct net_device *dev = qdisc_dev(sch); + struct tc_mq_qopt_offload opt = { + .command = cmd, + .handle = sch->handle, + }; + + if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc) + return -EOPNOTSUPP; + + return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_MQ, &opt); +} + static void mq_destroy(struct Qdisc *sch) { struct net_device *dev = qdisc_dev(sch); struct mq_sched *priv = qdisc_priv(sch); unsigned int ntx; + mq_offload(sch, TC_MQ_DESTROY); + if (!priv->qdiscs) return; for (ntx = 0; ntx < dev->num_tx_queues && priv->qdiscs[ntx]; ntx++) @@ -70,6 +87,8 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt, } sch->flags |= TCQ_F_MQROOT; + + mq_offload(sch, TC_MQ_CREATE); return 0; } |