diff mbox series

[net,v3] iavf: Fix max_rate limiting

Message ID 20220609214315.548305-1-xuejun.zhang@intel.com
State Changes Requested
Headers show
Series [net,v3] iavf: Fix max_rate limiting | expand

Commit Message

Zhang, Xuejun June 9, 2022, 9:43 p.m. UTC
From: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>

Fix max_rate option in tc, check for proper quanta boundaries.
Check for minimum value provided and if it fits expected 50Mbps
quanta.

Without this patch, iavf could send settings for max_rate limiting
that would be accepted from by PF even the max_rate option is less
than expected 50Mbps quanta. It results in no rate limiting
on traffic as rate limiting will be floored to 0.

Example:
tc qdisc add dev $vf root mqprio num_tc 3 map 0 2 1 queues \
2@0 2@2 2@4 hw 1 mode channel shaper bw_rlimit \
max_rate 50Mbps 500Mbps 500Mbps

Should limit TC0 to circa 50 Mbps

tc qdisc add dev $vf root mqprio num_tc 3 map 0 2 1 queues \
2@0 2@2 2@4 hw 1 mode channel shaper bw_rlimit \
max_rate 0Mbps 100Kbit 500Mbps

Should return error

Fixes: d5b33d0 ("i40evf: add ndo_setup_tc callback to i40evf")
Signed-off-by: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
Signed-off-by: Jun Zhang <xuejun.zhang@intel.com>
---
v2: Change author to Przemyslaw, and change variable to RCT
v3: Add space between title & commit message body
---
 drivers/net/ethernet/intel/iavf/iavf.h      |  1 +
 drivers/net/ethernet/intel/iavf/iavf_main.c | 24 +++++++++++++++++++--
 2 files changed, 23 insertions(+), 2 deletions(-)

Comments

Tony Nguyen June 10, 2022, 5:30 p.m. UTC | #1
On 6/9/2022 2:43 PM, Jun Zhang wrote:
> From: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
> 
> Fix max_rate option in tc, check for proper quanta boundaries.
> Check for minimum value provided and if it fits expected 50Mbps
> quanta.
> 
> Without this patch, iavf could send settings for max_rate limiting
> that would be accepted from by PF even the max_rate option is less
> than expected 50Mbps quanta. It results in no rate limiting
> on traffic as rate limiting will be floored to 0.
> 
> Example:
> tc qdisc add dev $vf root mqprio num_tc 3 map 0 2 1 queues \
> 2@0 2@2 2@4 hw 1 mode channel shaper bw_rlimit \
> max_rate 50Mbps 500Mbps 500Mbps
> 
> Should limit TC0 to circa 50 Mbps
> 
> tc qdisc add dev $vf root mqprio num_tc 3 map 0 2 1 queues \
> 2@0 2@2 2@4 hw 1 mode channel shaper bw_rlimit \
> max_rate 0Mbps 100Kbit 500Mbps
> 
> Should return error
> 
> Fixes: d5b33d0 ("i40evf: add ndo_setup_tc callback to i40evf")

The fixes tag should be 12 chars [1].

Commit: b181df353c12 ("iavf: Fix max_rate limiting")
	Fixes tag: Fixes: d5b33d0 ("i40evf: add ndo_setup_tc callback to i40evf")
	Has these problem(s):
		- SHA1 should be at least 12 digits long
		  Can be fixed by setting core.abbrev to 12 (or more) or (for git v2.11
		  or later) just making sure it is not set (or set to "auto").


> Signed-off-by: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
> Signed-off-by: Jun Zhang <xuejun.zhang@intel.com>

[1] 
https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-changes
diff mbox series

Patch

diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
index fda1198d2c00..0bd516ecebef 100644
--- a/drivers/net/ethernet/intel/iavf/iavf.h
+++ b/drivers/net/ethernet/intel/iavf/iavf.h
@@ -93,6 +93,7 @@  struct iavf_vsi {
 #define IAVF_HKEY_ARRAY_SIZE ((IAVF_VFQF_HKEY_MAX_INDEX + 1) * 4)
 #define IAVF_HLUT_ARRAY_SIZE ((IAVF_VFQF_HLUT_MAX_INDEX + 1) * 4)
 #define IAVF_MBPS_DIVISOR	125000 /* divisor to convert to Mbps */
+#define IAVF_MBPS_QUANTA	50
 
 #define IAVF_VIRTCHNL_VF_RESOURCE_SIZE (sizeof(struct virtchnl_vf_resource) + \
 					(IAVF_MAX_VF_VSI * \
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
index 57c51a15bcbc..b8bf472346c7 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
@@ -3409,6 +3409,7 @@  static int iavf_validate_ch_config(struct iavf_adapter *adapter,
 				   struct tc_mqprio_qopt_offload *mqprio_qopt)
 {
 	u64 total_max_rate = 0;
+	u32 tx_rate_rem = 0;
 	int i, num_qps = 0;
 	u64 tx_rate = 0;
 	int ret = 0;
@@ -3423,12 +3424,31 @@  static int iavf_validate_ch_config(struct iavf_adapter *adapter,
 			return -EINVAL;
 		if (mqprio_qopt->min_rate[i]) {
 			dev_err(&adapter->pdev->dev,
-				"Invalid min tx rate (greater than 0) specified\n");
+				"Invalid min tx rate (greater than 0) specified for TC%d\n", i);
 			return -EINVAL;
 		}
-		/*convert to Mbps */
+
+		/* convert to Mbps */
 		tx_rate = div_u64(mqprio_qopt->max_rate[i],
 				  IAVF_MBPS_DIVISOR);
+
+		if (mqprio_qopt->max_rate[i] &&
+		    tx_rate < IAVF_MBPS_QUANTA) {
+			dev_err(&adapter->pdev->dev,
+				"Invalid max tx rate for TC%d, minimum %dMbps\n",
+				i, IAVF_MBPS_QUANTA);
+			return -EINVAL;
+		}
+
+		(void)div_u64_rem(tx_rate, IAVF_MBPS_QUANTA, &tx_rate_rem);
+
+		if (tx_rate_rem != 0) {
+			dev_err(&adapter->pdev->dev,
+				"Invalid max tx rate for TC%d, not divisible by %d\n",
+				i, IAVF_MBPS_QUANTA);
+			return -EINVAL;
+		}
+
 		total_max_rate += tx_rate;
 		num_qps += mqprio_qopt->qopt.count[i];
 	}