Message ID | 20220609214315.548305-1-xuejun.zhang@intel.com |
---|---|
State | Changes Requested |
Headers | show |
Series | [net,v3] iavf: Fix max_rate limiting | expand |
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 --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]; }