diff mbox series

[net,2/2] net/mlx5: Fix flowhash key set/get for custom RSS

Message ID 20230723150658.241597-3-jdamato@fastly.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series rxfh with custom RSS fixes | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1343 this patch: 1343
netdev/cc_maintainers fail 1 blamed authors not CCed: maxtram95@gmail.com; 3 maintainers not CCed: maxtram95@gmail.com edumazet@google.com linux-rdma@vger.kernel.org
netdev/build_clang success Errors and warnings before: 1365 this patch: 1365
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 1366 this patch: 1366
netdev/checkpatch warning WARNING: line length of 81 exceeds 80 columns WARNING: line length of 89 exceeds 80 columns WARNING: line length of 90 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Joe Damato July 23, 2023, 3:06 p.m. UTC
mlx5 flow hash field retrieval and set only worked on the default
RSS context, not custom RSS contexts.

For example, before this patch attempting to retrieve the flow hash fields
for RSS context 1 fails:

$ sudo ethtool -u eth1 rx-flow-hash tcp4 context 1
Cannot get RX network flow hashing options: Invalid argument

This patch fixes getting and setting the flow hash fields for contexts
other than the default context.

Getting the flow hash fields for RSS context 1:

sudo ethtool -u eth1 rx-flow-hash tcp4 context 1
For RSS context 1:
TCP over IPV4 flows use these fields for computing Hash flow key:
IP DA

Now, setting the flash hash fields to a custom value:

sudo ethtool -U eth1 rx-flow-hash tcp4 sdfn context 1

And retrieving them again:

sudo ethtool -u eth1 rx-flow-hash tcp4 context 1
For RSS context 1:
TCP over IPV4 flows use these fields for computing Hash flow key:
IP SA
IP DA
L4 bytes 0 & 1 [TCP/UDP src port]
L4 bytes 2 & 3 [TCP/UDP dst port]

Fixes: f01cc58c18d6 ("net/mlx5e: Support multiple RSS contexts")
Signed-off-by: Joe Damato <jdamato@fastly.com>
---
 .../ethernet/mellanox/mlx5/core/en/rx_res.c   | 23 ++++++++++---
 .../ethernet/mellanox/mlx5/core/en/rx_res.h   |  5 +--
 .../mellanox/mlx5/core/en_fs_ethtool.c        | 33 ++++++++++++++-----
 3 files changed, 46 insertions(+), 15 deletions(-)

Comments

Tariq Toukan July 25, 2023, 9:59 a.m. UTC | #1
On 23/07/2023 18:06, Joe Damato wrote:
> mlx5 flow hash field retrieval and set only worked on the default
> RSS context, not custom RSS contexts.
> 
> For example, before this patch attempting to retrieve the flow hash fields
> for RSS context 1 fails:
> 

Hi,

You are adding new driver functionality, please take it through net-next.

> $ sudo ethtool -u eth1 rx-flow-hash tcp4 context 1
> Cannot get RX network flow hashing options: Invalid argument
> 
> This patch fixes getting and setting the flow hash fields for contexts
> other than the default context.
> 
> Getting the flow hash fields for RSS context 1:
> 
> sudo ethtool -u eth1 rx-flow-hash tcp4 context 1
> For RSS context 1:
> TCP over IPV4 flows use these fields for computing Hash flow key:
> IP DA
> 
> Now, setting the flash hash fields to a custom value:
> 
> sudo ethtool -U eth1 rx-flow-hash tcp4 sdfn context 1
> 
> And retrieving them again:
> 
> sudo ethtool -u eth1 rx-flow-hash tcp4 context 1
> For RSS context 1:
> TCP over IPV4 flows use these fields for computing Hash flow key:
> IP SA
> IP DA
> L4 bytes 0 & 1 [TCP/UDP src port]
> L4 bytes 2 & 3 [TCP/UDP dst port]
> 
> Fixes: f01cc58c18d6 ("net/mlx5e: Support multiple RSS contexts")
> Signed-off-by: Joe Damato <jdamato@fastly.com>
> ---
>   .../ethernet/mellanox/mlx5/core/en/rx_res.c   | 23 ++++++++++---
>   .../ethernet/mellanox/mlx5/core/en/rx_res.h   |  5 +--
>   .../mellanox/mlx5/core/en_fs_ethtool.c        | 33 ++++++++++++++-----
>   3 files changed, 46 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c
> index e1095bc36543..bb189c92e4c0 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c
> @@ -218,17 +218,32 @@ int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
>   	return mlx5e_rss_set_rxfh(rss, indir, key, hfunc, res->rss_rqns, res->rss_nch);
>   }
>   
> -u8 mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
> +int mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
> +				     u32 rss_idx)

For consistency with other functions, please keep the rss_idx next to 
the res argument.

>   {
> -	struct mlx5e_rss *rss = res->rss[0];
> +	struct mlx5e_rss *rss;
> +
> +	if (rss_idx >= MLX5E_MAX_NUM_RSS)
> +		return -EINVAL;
> +
> +	rss = res->rss[rss_idx];
> +	if (!rss)
> +		return -EINVAL;

return -ENOENT; in this case.

>   
>   	return mlx5e_rss_get_hash_fields(rss, tt);
>   }
>   
>   int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
> -				     u8 rx_hash_fields)
> +				     u8 rx_hash_fields, u32 rss_idx)

Same. let rss_idx come as second argument.
>   {
> -	struct mlx5e_rss *rss = res->rss[0];
> +	struct mlx5e_rss *rss;
> +
> +	if (rss_idx >= MLX5E_MAX_NUM_RSS)
> +		return -EINVAL;
> +
> +	rss = res->rss[rss_idx];
> +	if (!rss)
> +		return -EINVAL;

ENOENT

>   
>   	return mlx5e_rss_set_hash_fields(rss, tt, rx_hash_fields);
>   }
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.h b/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.h
> index 5d5f64fab60f..8ac9d67a9603 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.h
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.h
> @@ -48,9 +48,10 @@ int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
>   int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
>   			      const u32 *indir, const u8 *key, const u8 *hfunc);
>   
> -u8 mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt);
> +int mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
> +				     u32 rss_idx);
>   int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
> -				     u8 rx_hash_fields);
> +				     u8 rx_hash_fields, u32 rss_idx);
>   int mlx5e_rx_res_packet_merge_set_param(struct mlx5e_rx_res *res,
>   					struct mlx5e_packet_merge_param *pkt_merge_param);
>   
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
> index aac32e505c14..50b8f3da4db1 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
> @@ -902,8 +902,14 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
>   	u8 rx_hash_field = 0;
>   	int err;
>   	int tt;
> +	u32 flow_type = 0;
> +	u32 rss_idx = 0;
>   
> -	tt = flow_type_to_traffic_type(nfc->flow_type);
> +	if (nfc->flow_type & FLOW_RSS)
> +		rss_idx = nfc->rss_context;
> +
> +	flow_type = flow_type_mask(nfc->flow_type);
> +	tt = flow_type_to_traffic_type(flow_type);
>   	if (tt < 0)
>   		return tt;
>   
> @@ -911,10 +917,10 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
>   	 *  on src IP, dest IP, TCP/UDP src port and TCP/UDP dest
>   	 *  port.
>   	 */
> -	if (nfc->flow_type != TCP_V4_FLOW &&
> -	    nfc->flow_type != TCP_V6_FLOW &&
> -	    nfc->flow_type != UDP_V4_FLOW &&
> -	    nfc->flow_type != UDP_V6_FLOW)
> +	if (flow_type != TCP_V4_FLOW &&
> +	    flow_type != TCP_V6_FLOW &&
> +	    flow_type != UDP_V4_FLOW &&
> +	    flow_type != UDP_V6_FLOW)
>   		return -EOPNOTSUPP;
>   
>   	if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
> @@ -931,7 +937,7 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
>   		rx_hash_field |= MLX5_HASH_FIELD_SEL_L4_DPORT;
>   
>   	mutex_lock(&priv->state_lock);
> -	err = mlx5e_rx_res_rss_set_hash_fields(priv->rx_res, tt, rx_hash_field);
> +	err = mlx5e_rx_res_rss_set_hash_fields(priv->rx_res, tt, rx_hash_field, rss_idx);
>   	mutex_unlock(&priv->state_lock);
>   
>   	return err;
> @@ -940,14 +946,23 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
>   static int mlx5e_get_rss_hash_opt(struct mlx5e_priv *priv,
>   				  struct ethtool_rxnfc *nfc)
>   {
> -	u32 hash_field = 0;
> +	int hash_field = 0;
>   	int tt;
> +	u32 flow_type = 0;
> +	u32 rss_idx = 0;

Please maintain the reversed Christmas tree.

> +
> +	if (nfc->flow_type & FLOW_RSS)
> +		rss_idx = nfc->rss_context;
>   
> -	tt = flow_type_to_traffic_type(nfc->flow_type);
> +	flow_type = flow_type_mask(nfc->flow_type);
> +	tt = flow_type_to_traffic_type(flow_type);
>   	if (tt < 0)
>   		return tt;
>   
> -	hash_field = mlx5e_rx_res_rss_get_hash_fields(priv->rx_res, tt);
> +	hash_field = mlx5e_rx_res_rss_get_hash_fields(priv->rx_res, tt, rss_idx);
> +	if (hash_field < 0)
> +		return hash_field;
> +
>   	nfc->data = 0;
>   
>   	if (hash_field & MLX5_HASH_FIELD_SEL_SRC_IP)
Joe Damato July 26, 2023, 8:28 a.m. UTC | #2
On Tue, Jul 25, 2023 at 12:59:32PM +0300, Tariq Toukan wrote:
>
>
> On 23/07/2023 18:06, Joe Damato wrote:
> >mlx5 flow hash field retrieval and set only worked on the default
> >RSS context, not custom RSS contexts.
> >
> >For example, before this patch attempting to retrieve the flow hash fields
> >for RSS context 1 fails:
> >
>
> Hi,
>
> You are adding new driver functionality, please take it through net-next.

Thanks for reviewing the code I sent; I made the changes you requested and
sent a v2, but through net-next this time.
diff mbox series

Patch

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c
index e1095bc36543..bb189c92e4c0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c
@@ -218,17 +218,32 @@  int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
 	return mlx5e_rss_set_rxfh(rss, indir, key, hfunc, res->rss_rqns, res->rss_nch);
 }
 
-u8 mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
+int mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
+				     u32 rss_idx)
 {
-	struct mlx5e_rss *rss = res->rss[0];
+	struct mlx5e_rss *rss;
+
+	if (rss_idx >= MLX5E_MAX_NUM_RSS)
+		return -EINVAL;
+
+	rss = res->rss[rss_idx];
+	if (!rss)
+		return -EINVAL;
 
 	return mlx5e_rss_get_hash_fields(rss, tt);
 }
 
 int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
-				     u8 rx_hash_fields)
+				     u8 rx_hash_fields, u32 rss_idx)
 {
-	struct mlx5e_rss *rss = res->rss[0];
+	struct mlx5e_rss *rss;
+
+	if (rss_idx >= MLX5E_MAX_NUM_RSS)
+		return -EINVAL;
+
+	rss = res->rss[rss_idx];
+	if (!rss)
+		return -EINVAL;
 
 	return mlx5e_rss_set_hash_fields(rss, tt, rx_hash_fields);
 }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.h b/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.h
index 5d5f64fab60f..8ac9d67a9603 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.h
@@ -48,9 +48,10 @@  int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
 int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
 			      const u32 *indir, const u8 *key, const u8 *hfunc);
 
-u8 mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt);
+int mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
+				     u32 rss_idx);
 int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
-				     u8 rx_hash_fields);
+				     u8 rx_hash_fields, u32 rss_idx);
 int mlx5e_rx_res_packet_merge_set_param(struct mlx5e_rx_res *res,
 					struct mlx5e_packet_merge_param *pkt_merge_param);
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
index aac32e505c14..50b8f3da4db1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
@@ -902,8 +902,14 @@  static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
 	u8 rx_hash_field = 0;
 	int err;
 	int tt;
+	u32 flow_type = 0;
+	u32 rss_idx = 0;
 
-	tt = flow_type_to_traffic_type(nfc->flow_type);
+	if (nfc->flow_type & FLOW_RSS)
+		rss_idx = nfc->rss_context;
+
+	flow_type = flow_type_mask(nfc->flow_type);
+	tt = flow_type_to_traffic_type(flow_type);
 	if (tt < 0)
 		return tt;
 
@@ -911,10 +917,10 @@  static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
 	 *  on src IP, dest IP, TCP/UDP src port and TCP/UDP dest
 	 *  port.
 	 */
-	if (nfc->flow_type != TCP_V4_FLOW &&
-	    nfc->flow_type != TCP_V6_FLOW &&
-	    nfc->flow_type != UDP_V4_FLOW &&
-	    nfc->flow_type != UDP_V6_FLOW)
+	if (flow_type != TCP_V4_FLOW &&
+	    flow_type != TCP_V6_FLOW &&
+	    flow_type != UDP_V4_FLOW &&
+	    flow_type != UDP_V6_FLOW)
 		return -EOPNOTSUPP;
 
 	if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
@@ -931,7 +937,7 @@  static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
 		rx_hash_field |= MLX5_HASH_FIELD_SEL_L4_DPORT;
 
 	mutex_lock(&priv->state_lock);
-	err = mlx5e_rx_res_rss_set_hash_fields(priv->rx_res, tt, rx_hash_field);
+	err = mlx5e_rx_res_rss_set_hash_fields(priv->rx_res, tt, rx_hash_field, rss_idx);
 	mutex_unlock(&priv->state_lock);
 
 	return err;
@@ -940,14 +946,23 @@  static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
 static int mlx5e_get_rss_hash_opt(struct mlx5e_priv *priv,
 				  struct ethtool_rxnfc *nfc)
 {
-	u32 hash_field = 0;
+	int hash_field = 0;
 	int tt;
+	u32 flow_type = 0;
+	u32 rss_idx = 0;
+
+	if (nfc->flow_type & FLOW_RSS)
+		rss_idx = nfc->rss_context;
 
-	tt = flow_type_to_traffic_type(nfc->flow_type);
+	flow_type = flow_type_mask(nfc->flow_type);
+	tt = flow_type_to_traffic_type(flow_type);
 	if (tt < 0)
 		return tt;
 
-	hash_field = mlx5e_rx_res_rss_get_hash_fields(priv->rx_res, tt);
+	hash_field = mlx5e_rx_res_rss_get_hash_fields(priv->rx_res, tt, rss_idx);
+	if (hash_field < 0)
+		return hash_field;
+
 	nfc->data = 0;
 
 	if (hash_field & MLX5_HASH_FIELD_SEL_SRC_IP)