Skip to content

Commit be92377

Browse files
committed
Merge branch 'rxfh-custom-rss'
Joe Damato says: ==================== rxfh with custom RSS fixes Greetings: Welcome to v2, now via net-next. No functional changes; only style changes (see the summary below). While attempting to get the RX flow hash key for a custom RSS context on my mlx5 NIC, I got an error: $ sudo ethtool -u eth1 rx-flow-hash tcp4 context 1 Cannot get RX network flow hashing options: Invalid argument I dug into this a bit and noticed two things: 1. ETHTOOL_GRXFH supports custom RSS contexts, but ETHTOOL_SRXFH does not. I moved the copy logic out of ETHTOOL_GRXFH and into a helper so that both ETHTOOL_{G,S}RXFH now call it, which fixes ETHTOOL_SRXFH. This is patch 1/2. 2. mlx5 defaulted to RSS context 0 for both ETHTOOL_{G,S}RXFH paths. I have modified the driver to support custom contexts for both paths. It is now possible to get and set the flow hash key for custom RSS contexts with mlx5. This is patch 2/2. See commit messages for more details. Thanks. v2: - Rebased on net-next - Adjusted arguments of mlx5e_rx_res_rss_get_hash_fields and mlx5e_rx_res_rss_set_hash_fields to move rss_idx next to the rss argument - Changed return value of both mlx5e_rx_res_rss_get_hash_fields and mlx5e_rx_res_rss_set_hash_fields to -ENOENT when the rss entry is NULL - Changed order of local variables in mlx5e_get_rss_hash_opt and mlx5e_set_rss_hash_opt ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 3d40aed + 0212e5d commit be92377

File tree

4 files changed

+86
-54
lines changed

4 files changed

+86
-54
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -218,17 +218,32 @@ int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
218218
return mlx5e_rss_set_rxfh(rss, indir, key, hfunc, res->rss_rqns, res->rss_nch);
219219
}
220220

221-
u8 mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
221+
int mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, u32 rss_idx,
222+
enum mlx5_traffic_types tt)
222223
{
223-
struct mlx5e_rss *rss = res->rss[0];
224+
struct mlx5e_rss *rss;
225+
226+
if (rss_idx >= MLX5E_MAX_NUM_RSS)
227+
return -EINVAL;
228+
229+
rss = res->rss[rss_idx];
230+
if (!rss)
231+
return -ENOENT;
224232

225233
return mlx5e_rss_get_hash_fields(rss, tt);
226234
}
227235

228-
int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
229-
u8 rx_hash_fields)
236+
int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, u32 rss_idx,
237+
enum mlx5_traffic_types tt, u8 rx_hash_fields)
230238
{
231-
struct mlx5e_rss *rss = res->rss[0];
239+
struct mlx5e_rss *rss;
240+
241+
if (rss_idx >= MLX5E_MAX_NUM_RSS)
242+
return -EINVAL;
243+
244+
rss = res->rss[rss_idx];
245+
if (!rss)
246+
return -ENOENT;
232247

233248
return mlx5e_rss_set_hash_fields(rss, tt, rx_hash_fields);
234249
}

drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@ int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
4848
int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
4949
const u32 *indir, const u8 *key, const u8 *hfunc);
5050

51-
u8 mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt);
52-
int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
53-
u8 rx_hash_fields);
51+
int mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, u32 rss_idx,
52+
enum mlx5_traffic_types tt);
53+
int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, u32 rss_idx,
54+
enum mlx5_traffic_types tt, u8 rx_hash_fields);
5455
int mlx5e_rx_res_packet_merge_set_param(struct mlx5e_rx_res *res,
5556
struct mlx5e_packet_merge_param *pkt_merge_param);
5657

drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -900,21 +900,27 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
900900
struct ethtool_rxnfc *nfc)
901901
{
902902
u8 rx_hash_field = 0;
903+
u32 flow_type = 0;
904+
u32 rss_idx = 0;
903905
int err;
904906
int tt;
905907

906-
tt = flow_type_to_traffic_type(nfc->flow_type);
908+
if (nfc->flow_type & FLOW_RSS)
909+
rss_idx = nfc->rss_context;
910+
911+
flow_type = flow_type_mask(nfc->flow_type);
912+
tt = flow_type_to_traffic_type(flow_type);
907913
if (tt < 0)
908914
return tt;
909915

910916
/* RSS does not support anything other than hashing to queues
911917
* on src IP, dest IP, TCP/UDP src port and TCP/UDP dest
912918
* port.
913919
*/
914-
if (nfc->flow_type != TCP_V4_FLOW &&
915-
nfc->flow_type != TCP_V6_FLOW &&
916-
nfc->flow_type != UDP_V4_FLOW &&
917-
nfc->flow_type != UDP_V6_FLOW)
920+
if (flow_type != TCP_V4_FLOW &&
921+
flow_type != TCP_V6_FLOW &&
922+
flow_type != UDP_V4_FLOW &&
923+
flow_type != UDP_V6_FLOW)
918924
return -EOPNOTSUPP;
919925

920926
if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
@@ -931,7 +937,7 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
931937
rx_hash_field |= MLX5_HASH_FIELD_SEL_L4_DPORT;
932938

933939
mutex_lock(&priv->state_lock);
934-
err = mlx5e_rx_res_rss_set_hash_fields(priv->rx_res, tt, rx_hash_field);
940+
err = mlx5e_rx_res_rss_set_hash_fields(priv->rx_res, rss_idx, tt, rx_hash_field);
935941
mutex_unlock(&priv->state_lock);
936942

937943
return err;
@@ -940,14 +946,23 @@ static int mlx5e_set_rss_hash_opt(struct mlx5e_priv *priv,
940946
static int mlx5e_get_rss_hash_opt(struct mlx5e_priv *priv,
941947
struct ethtool_rxnfc *nfc)
942948
{
943-
u32 hash_field = 0;
949+
int hash_field = 0;
950+
u32 flow_type = 0;
951+
u32 rss_idx = 0;
944952
int tt;
945953

946-
tt = flow_type_to_traffic_type(nfc->flow_type);
954+
if (nfc->flow_type & FLOW_RSS)
955+
rss_idx = nfc->rss_context;
956+
957+
flow_type = flow_type_mask(nfc->flow_type);
958+
tt = flow_type_to_traffic_type(flow_type);
947959
if (tt < 0)
948960
return tt;
949961

950-
hash_field = mlx5e_rx_res_rss_get_hash_fields(priv->rx_res, tt);
962+
hash_field = mlx5e_rx_res_rss_get_hash_fields(priv->rx_res, rss_idx, tt);
963+
if (hash_field < 0)
964+
return hash_field;
965+
951966
nfc->data = 0;
952967

953968
if (hash_field & MLX5_HASH_FIELD_SEL_SRC_IP)

net/ethtool/ioctl.c

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,38 @@ static int ethtool_rxnfc_copy_to_compat(void __user *useraddr,
907907
return 0;
908908
}
909909

910+
static int ethtool_rxnfc_copy_struct(u32 cmd, struct ethtool_rxnfc *info,
911+
size_t *info_size, void __user *useraddr)
912+
{
913+
/* struct ethtool_rxnfc was originally defined for
914+
* ETHTOOL_{G,S}RXFH with only the cmd, flow_type and data
915+
* members. User-space might still be using that
916+
* definition.
917+
*/
918+
if (cmd == ETHTOOL_GRXFH || cmd == ETHTOOL_SRXFH)
919+
*info_size = (offsetof(struct ethtool_rxnfc, data) +
920+
sizeof(info->data));
921+
922+
if (ethtool_rxnfc_copy_from_user(info, useraddr, *info_size))
923+
return -EFAULT;
924+
925+
if ((cmd == ETHTOOL_GRXFH || cmd == ETHTOOL_SRXFH) && info->flow_type & FLOW_RSS) {
926+
*info_size = sizeof(*info);
927+
if (ethtool_rxnfc_copy_from_user(info, useraddr, *info_size))
928+
return -EFAULT;
929+
/* Since malicious users may modify the original data,
930+
* we need to check whether FLOW_RSS is still requested.
931+
*/
932+
if (!(info->flow_type & FLOW_RSS))
933+
return -EINVAL;
934+
}
935+
936+
if (info->cmd != cmd)
937+
return -EINVAL;
938+
939+
return 0;
940+
}
941+
910942
static int ethtool_rxnfc_copy_to_user(void __user *useraddr,
911943
const struct ethtool_rxnfc *rxnfc,
912944
size_t size, const u32 *rule_buf)
@@ -944,16 +976,9 @@ static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev,
944976
if (!dev->ethtool_ops->set_rxnfc)
945977
return -EOPNOTSUPP;
946978

947-
/* struct ethtool_rxnfc was originally defined for
948-
* ETHTOOL_{G,S}RXFH with only the cmd, flow_type and data
949-
* members. User-space might still be using that
950-
* definition. */
951-
if (cmd == ETHTOOL_SRXFH)
952-
info_size = (offsetof(struct ethtool_rxnfc, data) +
953-
sizeof(info.data));
954-
955-
if (ethtool_rxnfc_copy_from_user(&info, useraddr, info_size))
956-
return -EFAULT;
979+
rc = ethtool_rxnfc_copy_struct(cmd, &info, &info_size, useraddr);
980+
if (rc)
981+
return rc;
957982

958983
rc = dev->ethtool_ops->set_rxnfc(dev, &info);
959984
if (rc)
@@ -978,33 +1003,9 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev,
9781003
if (!ops->get_rxnfc)
9791004
return -EOPNOTSUPP;
9801005

981-
/* struct ethtool_rxnfc was originally defined for
982-
* ETHTOOL_{G,S}RXFH with only the cmd, flow_type and data
983-
* members. User-space might still be using that
984-
* definition. */
985-
if (cmd == ETHTOOL_GRXFH)
986-
info_size = (offsetof(struct ethtool_rxnfc, data) +
987-
sizeof(info.data));
988-
989-
if (ethtool_rxnfc_copy_from_user(&info, useraddr, info_size))
990-
return -EFAULT;
991-
992-
/* If FLOW_RSS was requested then user-space must be using the
993-
* new definition, as FLOW_RSS is newer.
994-
*/
995-
if (cmd == ETHTOOL_GRXFH && info.flow_type & FLOW_RSS) {
996-
info_size = sizeof(info);
997-
if (ethtool_rxnfc_copy_from_user(&info, useraddr, info_size))
998-
return -EFAULT;
999-
/* Since malicious users may modify the original data,
1000-
* we need to check whether FLOW_RSS is still requested.
1001-
*/
1002-
if (!(info.flow_type & FLOW_RSS))
1003-
return -EINVAL;
1004-
}
1005-
1006-
if (info.cmd != cmd)
1007-
return -EINVAL;
1006+
ret = ethtool_rxnfc_copy_struct(cmd, &info, &info_size, useraddr);
1007+
if (ret)
1008+
return ret;
10081009

10091010
if (info.cmd == ETHTOOL_GRXCLSRLALL) {
10101011
if (info.rule_cnt > 0) {

0 commit comments

Comments
 (0)