[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230120141537.1350744-5-vladimir.oltean@nxp.com>
Date: Fri, 20 Jan 2023 16:15:30 +0200
From: Vladimir Oltean <vladimir.oltean@....com>
To: netdev@...r.kernel.org, John Fastabend <john.fastabend@...il.com>
Cc: "David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Claudiu Manoil <claudiu.manoil@....com>,
Camelia Groza <camelia.groza@....com>,
Xiaoliang Yang <xiaoliang.yang_1@....com>,
Gerhard Engleder <gerhard@...leder-embedded.com>,
Vinicius Costa Gomes <vinicius.gomes@...el.com>,
Alexander Duyck <alexander.duyck@...il.com>,
Kurt Kanzenbach <kurt@...utronix.de>,
Ferenc Fejes <ferenc.fejes@...csson.com>,
Tony Nguyen <anthony.l.nguyen@...el.com>,
Jesse Brandeburg <jesse.brandeburg@...el.com>,
Jacob Keller <jacob.e.keller@...el.com>
Subject: [RFC PATCH net-next 04/11] net/sched: mqprio: allow offloading drivers to request queue count validation
mqprio_parse_opt() proudly has a comment:
/* If hardware offload is requested we will leave it to the device
* to either populate the queue counts itself or to validate the
* provided queue counts.
*/
Unfortunately some device drivers did not get this memo, and don't
validate the queue counts.
Introduce a tc capability, and make mqprio query it.
Signed-off-by: Vladimir Oltean <vladimir.oltean@....com>
---
include/net/pkt_sched.h | 4 +++
net/sched/sch_mqprio.c | 58 +++++++++++++++++++++++++++--------------
2 files changed, 42 insertions(+), 20 deletions(-)
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 6c5e64e0a0bb..02e3ccfbc7d1 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -160,6 +160,10 @@ struct tc_etf_qopt_offload {
s32 queue;
};
+struct tc_mqprio_caps {
+ bool validate_queue_counts:1;
+};
+
struct tc_mqprio_qopt_offload {
/* struct tc_mqprio_qopt must always be the first element */
struct tc_mqprio_qopt qopt;
diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
index 3579a64da06e..5fdceab82ea1 100644
--- a/net/sched/sch_mqprio.c
+++ b/net/sched/sch_mqprio.c
@@ -27,14 +27,50 @@ struct mqprio_sched {
u64 max_rate[TC_QOPT_MAX_QUEUE];
};
+static int mqprio_validate_queue_counts(struct net_device *dev,
+ const struct tc_mqprio_qopt *qopt)
+{
+ int i, j;
+
+ for (i = 0; i < qopt->num_tc; i++) {
+ unsigned int last = qopt->offset[i] + qopt->count[i];
+
+ /* Verify the queue count is in tx range being equal to the
+ * real_num_tx_queues indicates the last queue is in use.
+ */
+ if (qopt->offset[i] >= dev->real_num_tx_queues ||
+ !qopt->count[i] ||
+ last > dev->real_num_tx_queues)
+ return -EINVAL;
+
+ /* Verify that the offset and counts do not overlap */
+ for (j = i + 1; j < qopt->num_tc; j++) {
+ if (last > qopt->offset[j])
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int mqprio_enable_offload(struct Qdisc *sch,
const struct tc_mqprio_qopt *qopt)
{
struct tc_mqprio_qopt_offload mqprio = {.qopt = *qopt};
struct mqprio_sched *priv = qdisc_priv(sch);
struct net_device *dev = qdisc_dev(sch);
+ struct tc_mqprio_caps caps;
int err, i;
+ qdisc_offload_query_caps(dev, TC_SETUP_QDISC_MQPRIO,
+ &caps, sizeof(caps));
+
+ if (caps.validate_queue_counts) {
+ err = mqprio_validate_queue_counts(dev, qopt);
+ if (err)
+ return err;
+ }
+
switch (priv->mode) {
case TC_MQPRIO_MODE_DCB:
if (priv->shaper != TC_MQPRIO_SHAPER_DCB)
@@ -104,7 +140,7 @@ static void mqprio_destroy(struct Qdisc *sch)
static int mqprio_parse_opt(struct net_device *dev, struct tc_mqprio_qopt *qopt)
{
- int i, j;
+ int i;
/* Verify num_tc is not out of max range */
if (qopt->num_tc > TC_MAX_QUEUE)
@@ -131,25 +167,7 @@ static int mqprio_parse_opt(struct net_device *dev, struct tc_mqprio_qopt *qopt)
if (qopt->hw)
return dev->netdev_ops->ndo_setup_tc ? 0 : -EINVAL;
- for (i = 0; i < qopt->num_tc; i++) {
- unsigned int last = qopt->offset[i] + qopt->count[i];
-
- /* Verify the queue count is in tx range being equal to the
- * real_num_tx_queues indicates the last queue is in use.
- */
- if (qopt->offset[i] >= dev->real_num_tx_queues ||
- !qopt->count[i] ||
- last > dev->real_num_tx_queues)
- return -EINVAL;
-
- /* Verify that the offset and counts do not overlap */
- for (j = i + 1; j < qopt->num_tc; j++) {
- if (last > qopt->offset[j])
- return -EINVAL;
- }
- }
-
- return 0;
+ return mqprio_validate_queue_counts(dev, qopt);
}
static const struct nla_policy mqprio_policy[TCA_MQPRIO_MAX + 1] = {
--
2.34.1
Powered by blists - more mailing lists