Commit 0212e5d9 authored by Joe Damato's avatar Joe Damato Committed by David S. Miller

net/mlx5: Fix flowhash key set/get for custom RSS

mlx5 flow hash field retrieval and set only worked on the default
RSS context as of commit f01cc58c ("net/mlx5e: Support multiple RSS
contexts"), 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]
Signed-off-by: default avatarJoe Damato <jdamato@fastly.com>
Reviewed-by: default avatarTariq Toukan <tariqt@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 801b27e8
...@@ -218,17 +218,32 @@ int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx, ...@@ -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); 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, u32 rss_idx,
enum mlx5_traffic_types tt)
{ {
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 -ENOENT;
return mlx5e_rss_get_hash_fields(rss, tt); 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, int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, u32 rss_idx,
u8 rx_hash_fields) enum mlx5_traffic_types tt, u8 rx_hash_fields)
{ {
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 -ENOENT;
return mlx5e_rss_set_hash_fields(rss, tt, rx_hash_fields); return mlx5e_rss_set_hash_fields(rss, tt, rx_hash_fields);
} }
......
...@@ -48,9 +48,10 @@ int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx, ...@@ -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, int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
const u32 *indir, const u8 *key, const u8 *hfunc); 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, u32 rss_idx,
int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt, enum mlx5_traffic_types tt);
u8 rx_hash_fields); int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, u32 rss_idx,
enum mlx5_traffic_types tt, u8 rx_hash_fields);
int mlx5e_rx_res_packet_merge_set_param(struct mlx5e_rx_res *res, int mlx5e_rx_res_packet_merge_set_param(struct mlx5e_rx_res *res,
struct mlx5e_packet_merge_param *pkt_merge_param); struct mlx5e_packet_merge_param *pkt_merge_param);
......
...@@ -900,10 +900,16 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv, ...@@ -900,10 +900,16 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
struct ethtool_rxnfc *nfc) struct ethtool_rxnfc *nfc)
{ {
u8 rx_hash_field = 0; u8 rx_hash_field = 0;
u32 flow_type = 0;
u32 rss_idx = 0;
int err; int err;
int tt; int tt;
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) if (tt < 0)
return tt; return tt;
...@@ -911,10 +917,10 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv, ...@@ -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 * on src IP, dest IP, TCP/UDP src port and TCP/UDP dest
* port. * port.
*/ */
if (nfc->flow_type != TCP_V4_FLOW && if (flow_type != TCP_V4_FLOW &&
nfc->flow_type != TCP_V6_FLOW && flow_type != TCP_V6_FLOW &&
nfc->flow_type != UDP_V4_FLOW && flow_type != UDP_V4_FLOW &&
nfc->flow_type != UDP_V6_FLOW) flow_type != UDP_V6_FLOW)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST | if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
...@@ -931,7 +937,7 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv, ...@@ -931,7 +937,7 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
rx_hash_field |= MLX5_HASH_FIELD_SEL_L4_DPORT; rx_hash_field |= MLX5_HASH_FIELD_SEL_L4_DPORT;
mutex_lock(&priv->state_lock); 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, rss_idx, tt, rx_hash_field);
mutex_unlock(&priv->state_lock); mutex_unlock(&priv->state_lock);
return err; return err;
...@@ -940,14 +946,23 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv, ...@@ -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, static int mlx5e_get_rss_hash_opt(struct mlx5e_priv *priv,
struct ethtool_rxnfc *nfc) struct ethtool_rxnfc *nfc)
{ {
u32 hash_field = 0; int hash_field = 0;
u32 flow_type = 0;
u32 rss_idx = 0;
int tt; int tt;
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) if (tt < 0)
return tt; 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, rss_idx, tt);
if (hash_field < 0)
return hash_field;
nfc->data = 0; nfc->data = 0;
if (hash_field & MLX5_HASH_FIELD_SEL_SRC_IP) if (hash_field & MLX5_HASH_FIELD_SEL_SRC_IP)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment