[S24,v2,05/12] ice: Fix RSS LUT table when setting Rx channels
diff mbox series

Message ID 20190729090454.5501-5-anthony.l.nguyen@intel.com
State Changes Requested
Delegated to: Jeff Kirsher
Headers show
Series
  • [S24,v2,01/12] ice: Allow egress control packets from PF_VSI
Related show

Commit Message

Tony Nguyen July 29, 2019, 9:04 a.m. UTC
From: Brett Creeley <brett.creeley@intel.com>

Currently there are multiple problems involved with setting Rx channels
in regards to the RSS LUT. First, if the user set the indirection table
manually through ethtool, changing the Rx channels will blindly use the
user set value. Second when increasing the number of Rx channels the RSS
table size is doing of minimum of the last RSS table width and the newly
requested one, this is causing the previously set RSS table width to be
used.

Fix these issues by adding the function ice_pf_set_dflt_rss_lut() that
is called when changing the number of Rx channels. This function updates
the RSS LUT to the default configuration for the PF any time the user
has changed the number of Rx channels.

Signed-off-by: Brett Creeley <brett.creeley@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
v2: Change function to take VSI instead of PF
---
 drivers/net/ethernet/intel/ice/ice_ethtool.c | 63 ++++++++++++++++++++
 1 file changed, 63 insertions(+)

Comments

Bowers, AndrewX July 31, 2019, 5:10 p.m. UTC | #1
> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces@osuosl.org] On
> Behalf Of Tony Nguyen
> Sent: Monday, July 29, 2019 2:05 AM
> To: intel-wired-lan@lists.osuosl.org
> Subject: [Intel-wired-lan] [PATCH S24 v2 05/12] ice: Fix RSS LUT table when
> setting Rx channels
> 
> From: Brett Creeley <brett.creeley@intel.com>
> 
> Currently there are multiple problems involved with setting Rx channels in
> regards to the RSS LUT. First, if the user set the indirection table manually
> through ethtool, changing the Rx channels will blindly use the user set value.
> Second when increasing the number of Rx channels the RSS table size is
> doing of minimum of the last RSS table width and the newly requested one,
> this is causing the previously set RSS table width to be used.
> 
> Fix these issues by adding the function ice_pf_set_dflt_rss_lut() that is called
> when changing the number of Rx channels. This function updates the RSS
> LUT to the default configuration for the PF any time the user has changed the
> number of Rx channels.
> 
> Signed-off-by: Brett Creeley <brett.creeley@intel.com>
> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
> ---
> v2: Change function to take VSI instead of PF
> ---
>  drivers/net/ethernet/intel/ice/ice_ethtool.c | 63 ++++++++++++++++++++
>  1 file changed, 63 insertions(+)

Tested-by: Andrew Bowers <andrewx.bowers@intel.com>

Patch
diff mbox series

diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
index ba29aede99ad..2d37dd4ba677 100644
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
@@ -3154,6 +3154,66 @@  ice_get_channels(struct net_device *dev, struct ethtool_channels *ch)
 	ch->tx_count = vsi->num_txq;
 }
 
+/**
+ * ice_vsi_set_dflt_rss_lut - set default RSS LUT with requested RSS size
+ * @vsi: VSI to reconfigure RSS LUT on
+ * @req_rss_size: requested range of queue numbers for hashing
+ *
+ * Set the VSI's RSS parameters, configure the RSS LUT based on these, and then
+ * clear the previous vsi->rss_lut_user because it is assumed to be invalid at
+ * this point.
+ */
+static int ice_vsi_set_dflt_rss_lut(struct ice_vsi *vsi, int req_rss_size)
+{
+	struct ice_pf *pf = vsi->back;
+	enum ice_status status;
+	struct device *dev;
+	struct ice_hw *hw;
+	int err = 0;
+	u8 *lut;
+
+	dev = &pf->pdev->dev;
+	hw = &pf->hw;
+
+	if (!req_rss_size)
+		return -EINVAL;
+
+	lut = devm_kzalloc(dev, vsi->rss_table_size, GFP_KERNEL);
+	if (!lut)
+		return -ENOMEM;
+
+	/* set RSS LUT parameters */
+	if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) {
+		vsi->rss_size = 1;
+	} else {
+		struct ice_hw_common_caps *caps = &hw->func_caps.common_cap;
+
+		vsi->rss_size = min_t(int, req_rss_size,
+				      BIT(caps->rss_table_entry_width));
+	}
+
+	/* create/set RSS LUT */
+	ice_fill_rss_lut(lut, vsi->rss_table_size, vsi->rss_size);
+	status = ice_aq_set_rss_lut(hw, vsi->idx, vsi->rss_lut_type, lut,
+				    vsi->rss_table_size);
+	if (status) {
+		dev_err(dev, "Cannot set RSS lut, err %d aq_err %d\n",
+			status, hw->adminq.sq_last_status);
+		err = -EIO;
+	}
+
+	/* get rid of invalid user configuration */
+	if (vsi->rss_lut_user) {
+		netdev_info(vsi->netdev,
+			    "Rx queue count changed, clearing user modified RSS LUT, re-run ethtool [-x|-X] to [check|set] settings if needed\n");
+		devm_kfree(dev, vsi->rss_lut_user);
+		vsi->rss_lut_user = NULL;
+	}
+
+	devm_kfree(dev, lut);
+	return err;
+}
+
 /**
  * ice_set_channels - set the number channels
  * @dev: network interface device structure
@@ -3189,6 +3249,9 @@  static int ice_set_channels(struct net_device *dev, struct ethtool_channels *ch)
 
 	ice_vsi_recfg_qs(vsi, new_rx, new_tx);
 
+	if (new_rx)
+		return ice_vsi_set_dflt_rss_lut(vsi, new_rx);
+
 	return 0;
 }