lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Fri, 23 Apr 2021 14:12:20 -0700
From:   Amritha Nambiar <amritha.nambiar@...el.com>
To:     netdev@...r.kernel.org, davem@...emloft.net, kuba@...nel.org
Cc:     jhs@...atatu.com, jiri@...nulli.us, xiyou.wangcong@...il.com,
        john.fastabend@...il.com, alexander.duyck@...il.com,
        vinicius.gomes@...el.com, vedang.patel@...el.com,
        sridhar.samudrala@...el.com, amritha.nambiar@...el.com
Subject: [net-next,RFC PATCH] net: Extend TC limit beyond 16 to 255

Extend the max limit of TCs to 255 (max value of 8-bit num_tc)
from current max of 16. This would allow creating more than 16
queue-sets and offloading them on devices with large number of
queues using the mqprio scheduler.
Also, changed the static allocation of struct
tc_mqprio_qopt_offload mqprio to dynamic allocation on heap to
fit within frame size as the size of attributes increases
proportionally with the max number of TCs.

Signed-off-by: Amritha Nambiar <amritha.nambiar@...el.com>
---
 include/linux/netdevice.h      |    6 ++---
 include/uapi/linux/pkt_sched.h |    6 ++---
 net/core/dev.c                 |    2 +-
 net/sched/sch_mqprio.c         |   52 +++++++++++++++++++++++++++-------------
 net/sched/sch_taprio.c         |    6 ++---
 5 files changed, 45 insertions(+), 27 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 5cbc950b34df..676f245651d9 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -804,8 +804,8 @@ struct xps_dev_maps {
 
 #endif /* CONFIG_XPS */
 
-#define TC_MAX_QUEUE	16
-#define TC_BITMASK	15
+#define TC_MAX_QUEUE	255
+#define TC_BITMASK	255
 /* HW offloaded queuing disciplines txq count and offset maps */
 struct netdev_tc_txq {
 	u16 count;
@@ -2219,7 +2219,7 @@ struct net_device {
 #endif
 	s16			num_tc;
 	struct netdev_tc_txq	tc_to_txq[TC_MAX_QUEUE];
-	u8			prio_tc_map[TC_BITMASK + 1];
+	u8			prio_tc_map[TC_BITMASK];
 
 #if IS_ENABLED(CONFIG_FCOE)
 	unsigned int		fcoe_ddp_xid;
diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h
index 79a699f106b1..b5d733135900 100644
--- a/include/uapi/linux/pkt_sched.h
+++ b/include/uapi/linux/pkt_sched.h
@@ -692,8 +692,8 @@ struct tc_drr_stats {
 };
 
 /* MQPRIO */
-#define TC_QOPT_BITMASK 15
-#define TC_QOPT_MAX_QUEUE 16
+#define TC_QOPT_BITMASK 255
+#define TC_QOPT_MAX_QUEUE 255
 
 enum {
 	TC_MQPRIO_HW_OFFLOAD_NONE,	/* no offload requested */
@@ -721,7 +721,7 @@ enum {
 
 struct tc_mqprio_qopt {
 	__u8	num_tc;
-	__u8	prio_tc_map[TC_QOPT_BITMASK + 1];
+	__u8	prio_tc_map[TC_QOPT_BITMASK];
 	__u8	hw;
 	__u16	count[TC_QOPT_MAX_QUEUE];
 	__u16	offset[TC_QOPT_MAX_QUEUE];
diff --git a/net/core/dev.c b/net/core/dev.c
index d9bf63dbe4fd..fe1b0bd812a5 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2476,7 +2476,7 @@ static void netif_setup_tc(struct net_device *dev, unsigned int txq)
 	}
 
 	/* Invalidated prio to tc mappings set to TC0 */
-	for (i = 1; i < TC_BITMASK + 1; i++) {
+	for (i = 1; i < TC_BITMASK; i++) {
 		int q = netdev_get_prio_tc_map(dev, i);
 
 		tc = &dev->tc_to_txq[q];
diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
index 8766ab5b8788..70b1267ac92c 100644
--- a/net/sched/sch_mqprio.c
+++ b/net/sched/sch_mqprio.c
@@ -42,15 +42,21 @@ static void mqprio_destroy(struct Qdisc *sch)
 	}
 
 	if (priv->hw_offload && dev->netdev_ops->ndo_setup_tc) {
-		struct tc_mqprio_qopt_offload mqprio = { { 0 } };
-
 		switch (priv->mode) {
 		case TC_MQPRIO_MODE_DCB:
 		case TC_MQPRIO_MODE_CHANNEL:
+		{
+			struct tc_mqprio_qopt_offload *mqprio;
+
+			mqprio = kzalloc(sizeof(*mqprio), GFP_KERNEL);
+			if (!mqprio)
+				return;
 			dev->netdev_ops->ndo_setup_tc(dev,
 						      TC_SETUP_QDISC_MQPRIO,
-						      &mqprio);
+						      mqprio);
+			kfree(mqprio);
 			break;
+		}
 		default:
 			return;
 		}
@@ -68,7 +74,7 @@ static int mqprio_parse_opt(struct net_device *dev, struct tc_mqprio_qopt *qopt)
 		return -EINVAL;
 
 	/* Verify priority mapping uses valid tcs */
-	for (i = 0; i < TC_BITMASK + 1; i++) {
+	for (i = 0; i < TC_BITMASK; i++) {
 		if (qopt->prio_tc_map[i] >= qopt->num_tc)
 			return -EINVAL;
 	}
@@ -241,36 +247,48 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
 	 * supplied and verified mapping
 	 */
 	if (qopt->hw) {
-		struct tc_mqprio_qopt_offload mqprio = {.qopt = *qopt};
+		struct tc_mqprio_qopt_offload *mqprio;
+
+		mqprio = kzalloc(sizeof(*mqprio), GFP_KERNEL);
+		if (!mqprio)
+			return -ENOMEM;
+
+		mqprio->qopt = *qopt;
 
 		switch (priv->mode) {
 		case TC_MQPRIO_MODE_DCB:
-			if (priv->shaper != TC_MQPRIO_SHAPER_DCB)
+			if (priv->shaper != TC_MQPRIO_SHAPER_DCB) {
+				kfree(mqprio);
 				return -EINVAL;
+			}
 			break;
 		case TC_MQPRIO_MODE_CHANNEL:
-			mqprio.flags = priv->flags;
+			mqprio->flags = priv->flags;
 			if (priv->flags & TC_MQPRIO_F_MODE)
-				mqprio.mode = priv->mode;
+				mqprio->mode = priv->mode;
 			if (priv->flags & TC_MQPRIO_F_SHAPER)
-				mqprio.shaper = priv->shaper;
+				mqprio->shaper = priv->shaper;
 			if (priv->flags & TC_MQPRIO_F_MIN_RATE)
-				for (i = 0; i < mqprio.qopt.num_tc; i++)
-					mqprio.min_rate[i] = priv->min_rate[i];
+				for (i = 0; i < mqprio->qopt.num_tc; i++)
+					mqprio->min_rate[i] = priv->min_rate[i];
 			if (priv->flags & TC_MQPRIO_F_MAX_RATE)
-				for (i = 0; i < mqprio.qopt.num_tc; i++)
-					mqprio.max_rate[i] = priv->max_rate[i];
+				for (i = 0; i < mqprio->qopt.num_tc; i++)
+					mqprio->max_rate[i] = priv->max_rate[i];
 			break;
 		default:
+			kfree(mqprio);
 			return -EINVAL;
 		}
 		err = dev->netdev_ops->ndo_setup_tc(dev,
 						    TC_SETUP_QDISC_MQPRIO,
-						    &mqprio);
-		if (err)
+						    mqprio);
+		if (err) {
+			kfree(mqprio);
 			return err;
+		}
 
-		priv->hw_offload = mqprio.qopt.hw;
+		priv->hw_offload = mqprio->qopt.hw;
+		kfree(mqprio);
 	} else {
 		netdev_set_num_tc(dev, qopt->num_tc);
 		for (i = 0; i < qopt->num_tc; i++)
@@ -279,7 +297,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
 	}
 
 	/* Always use supplied priority mappings */
-	for (i = 0; i < TC_BITMASK + 1; i++)
+	for (i = 0; i < TC_BITMASK; i++)
 		netdev_set_prio_tc_map(dev, i, qopt->prio_tc_map[i]);
 
 	sch->flags |= TCQ_F_MQROOT;
diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
index 922ed6b91abb..3878c77ce91d 100644
--- a/net/sched/sch_taprio.c
+++ b/net/sched/sch_taprio.c
@@ -982,7 +982,7 @@ static int taprio_parse_mqprio_opt(struct net_device *dev,
 	}
 
 	/* Verify priority mapping uses valid tcs */
-	for (i = 0; i <= TC_BITMASK; i++) {
+	for (i = 0; i < TC_BITMASK; i++) {
 		if (qopt->prio_tc_map[i] >= qopt->num_tc) {
 			NL_SET_ERR_MSG(extack, "Invalid traffic class in priority to traffic class mapping");
 			return -EINVAL;
@@ -1437,7 +1437,7 @@ static int taprio_mqprio_cmp(const struct net_device *dev,
 		    dev->tc_to_txq[i].offset != mqprio->offset[i])
 			return -1;
 
-	for (i = 0; i <= TC_BITMASK; i++)
+	for (i = 0; i < TC_BITMASK; i++)
 		if (dev->prio_tc_map[i] != mqprio->prio_tc_map[i])
 			return -1;
 
@@ -1548,7 +1548,7 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
 					    mqprio->offset[i]);
 
 		/* Always use supplied priority mappings */
-		for (i = 0; i <= TC_BITMASK; i++)
+		for (i = 0; i < TC_BITMASK; i++)
 			netdev_set_prio_tc_map(dev, i,
 					       mqprio->prio_tc_map[i]);
 	}

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ