OSDN Git Service

i40e: Fix set max_tx_rate when it is lower than 1 Mbps
authorMichal Jaron <michalx.jaron@intel.com>
Thu, 1 Sep 2022 07:49:33 +0000 (09:49 +0200)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Mon, 19 Sep 2022 21:13:06 +0000 (14:13 -0700)
While converting max_tx_rate from bytes to Mbps, this value was set to 0,
if the original value was lower than 125000 bytes (1 Mbps). This would
cause no transmission rate limiting to occur. This happened due to lack of
check of max_tx_rate against the 1 Mbps value for max_tx_rate and the
following division by 125000. Fix this issue by adding a helper
i40e_bw_bytes_to_mbits() which sets max_tx_rate to minimum usable value of
50 Mbps, if its value is less than 1 Mbps, otherwise do the required
conversion by dividing by 125000.

Fixes: 5ecae4120a6b ("i40e: Refactor VF BW rate limiting")
Signed-off-by: Michal Jaron <michalx.jaron@intel.com>
Signed-off-by: Andrii Staikov <andrii.staikov@intel.com>
Tested-by: Bharathi Sreenivas <bharathi.sreenivas@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/i40e/i40e_main.c

index 10c1e1e..e3d9804 100644 (file)
@@ -5909,6 +5909,26 @@ static int i40e_get_link_speed(struct i40e_vsi *vsi)
 }
 
 /**
+ * i40e_bw_bytes_to_mbits - Convert max_tx_rate from bytes to mbits
+ * @vsi: Pointer to vsi structure
+ * @max_tx_rate: max TX rate in bytes to be converted into Mbits
+ *
+ * Helper function to convert units before send to set BW limit
+ **/
+static u64 i40e_bw_bytes_to_mbits(struct i40e_vsi *vsi, u64 max_tx_rate)
+{
+       if (max_tx_rate < I40E_BW_MBPS_DIVISOR) {
+               dev_warn(&vsi->back->pdev->dev,
+                        "Setting max tx rate to minimum usable value of 50Mbps.\n");
+               max_tx_rate = I40E_BW_CREDIT_DIVISOR;
+       } else {
+               do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
+       }
+
+       return max_tx_rate;
+}
+
+/**
  * i40e_set_bw_limit - setup BW limit for Tx traffic based on max_tx_rate
  * @vsi: VSI to be configured
  * @seid: seid of the channel/VSI
@@ -5930,10 +5950,10 @@ int i40e_set_bw_limit(struct i40e_vsi *vsi, u16 seid, u64 max_tx_rate)
                        max_tx_rate, seid);
                return -EINVAL;
        }
-       if (max_tx_rate && max_tx_rate < 50) {
+       if (max_tx_rate && max_tx_rate < I40E_BW_CREDIT_DIVISOR) {
                dev_warn(&pf->pdev->dev,
                         "Setting max tx rate to minimum usable value of 50Mbps.\n");
-               max_tx_rate = 50;
+               max_tx_rate = I40E_BW_CREDIT_DIVISOR;
        }
 
        /* Tx rate credits are in values of 50Mbps, 0 is disabled */
@@ -8224,9 +8244,9 @@ config_tc:
 
        if (i40e_is_tc_mqprio_enabled(pf)) {
                if (vsi->mqprio_qopt.max_rate[0]) {
-                       u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0];
+                       u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi,
+                                                 vsi->mqprio_qopt.max_rate[0]);
 
-                       do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
                        ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate);
                        if (!ret) {
                                u64 credits = max_tx_rate;
@@ -10971,10 +10991,10 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
        }
 
        if (vsi->mqprio_qopt.max_rate[0]) {
-               u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0];
+               u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi,
+                                                 vsi->mqprio_qopt.max_rate[0]);
                u64 credits = 0;
 
-               do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
                ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate);
                if (ret)
                        goto end_unlock;