]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
eth: mlx5: migrate to the *_rxfh_context ops
authorJakub Kicinski <kuba@kernel.org>
Mon, 7 Jul 2025 18:41:13 +0000 (11:41 -0700)
committerJakub Kicinski <kuba@kernel.org>
Tue, 8 Jul 2025 18:56:40 +0000 (11:56 -0700)
Convert mlx5 to dedicated RXFH ops. This is a fairly shallow
conversion, TBH, most of the driver code stays as is, but we
let the core allocate the context ID for the driver.

mlx5e_rx_res_rss_get_rxfh() and friends are made void, since
core only calls the driver for context 0. The second call
is right after context creation so it must exist (tm).

Tested with drivers/net/hw/rss_ctx.py on MCX6.

Reviewed-by: Gal Pressman <gal@nvidia.com>
Link: https://patch.msgid.link/20250707184115.2285277-4-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlx5/core/en/rss.c
drivers/net/ethernet/mellanox/mlx5/core/en/rss.h
drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c
drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.h
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c

index 74cd111ee320c29c443e0701779c3cca4b2014ae..c68ba0e58fa6beb4e35b809bab24536d9922a174 100644 (file)
@@ -567,7 +567,8 @@ inner_tir:
        return final_err;
 }
 
-int mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc, bool *symmetric)
+void mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc,
+                       bool *symmetric)
 {
        if (indir)
                memcpy(indir, rss->indir.table,
@@ -582,8 +583,6 @@ int mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc, bo
 
        if (symmetric)
                *symmetric = rss->hash.symmetric;
-
-       return 0;
 }
 
 int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
index 8ac902190010b9b47bf3ef0fe6458af7ab35ccc7..c6c1b2847cf53ff1f9d84187b7fe31672d153b15 100644 (file)
@@ -47,7 +47,8 @@ void mlx5e_rss_disable(struct mlx5e_rss *rss);
 
 int mlx5e_rss_packet_merge_set_param(struct mlx5e_rss *rss,
                                     struct mlx5e_packet_merge_param *pkt_merge_param);
-int mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc, bool *symmetric);
+void mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc,
+                       bool *symmetric);
 int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
                       const u8 *key, const u8 *hfunc, const bool *symmetric,
                       u32 *rqns, u32 *vhca_ids, unsigned int num_rqns);
index 5fcbe47337b080b57e6e6b224bb7e10d8f858cbf..e5cce2df364987c42d9cd7e9136086986d72fdb1 100644 (file)
@@ -71,17 +71,12 @@ static int mlx5e_rx_res_rss_init_def(struct mlx5e_rx_res *res,
        return 0;
 }
 
-int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 *rss_idx, unsigned int init_nch)
+int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 rss_idx, unsigned int init_nch)
 {
        bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
        struct mlx5e_rss *rss;
-       int i;
-
-       for (i = 1; i < MLX5E_MAX_NUM_RSS; i++)
-               if (!res->rss[i])
-                       break;
 
-       if (i == MLX5E_MAX_NUM_RSS)
+       if (WARN_ON_ONCE(res->rss[rss_idx]))
                return -ENOSPC;
 
        rss = mlx5e_rss_init(res->mdev, inner_ft_support, res->drop_rqn,
@@ -97,8 +92,7 @@ int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 *rss_idx, unsigned int i
                mlx5e_rss_enable(rss, res->rss_rqns, vhca_ids, res->rss_nch);
        }
 
-       res->rss[i] = rss;
-       *rss_idx = i;
+       res->rss[rss_idx] = rss;
 
        return 0;
 }
@@ -193,19 +187,17 @@ void mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res *res, unsigned int n
        mlx5e_rss_set_indir_uniform(res->rss[0], nch);
 }
 
-int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
-                             u32 *indir, u8 *key, u8 *hfunc, bool *symmetric)
+void mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
+                              u32 *indir, u8 *key, u8 *hfunc, bool *symmetric)
 {
-       struct mlx5e_rss *rss;
+       struct mlx5e_rss *rss = NULL;
 
-       if (rss_idx >= MLX5E_MAX_NUM_RSS)
-               return -EINVAL;
-
-       rss = res->rss[rss_idx];
-       if (!rss)
-               return -ENOENT;
+       if (rss_idx < MLX5E_MAX_NUM_RSS)
+               rss = res->rss[rss_idx];
+       if (WARN_ON_ONCE(!rss))
+               return;
 
-       return mlx5e_rss_get_rxfh(rss, indir, key, hfunc, symmetric);
+       mlx5e_rss_get_rxfh(rss, indir, key, hfunc, symmetric);
 }
 
 int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
index 3e09d91281af9d62ded00567650fe643b81d42c5..1d049e2aa2649b9b7ba61e0f20a5de5cbba01d58 100644 (file)
@@ -48,8 +48,9 @@ void mlx5e_rx_res_xsk_update(struct mlx5e_rx_res *res, struct mlx5e_channels *ch
 
 /* Configuration API */
 void mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res *res, unsigned int nch);
-int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
-                             u32 *indir, u8 *key, u8 *hfunc, bool *symmetric);
+void mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
+                              u32 *indir, u8 *key, u8 *hfunc,
+                              bool *symmetric);
 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 bool *symmetric);
@@ -61,7 +62,7 @@ int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, u32 rss_idx,
 int mlx5e_rx_res_packet_merge_set_param(struct mlx5e_rx_res *res,
                                        struct mlx5e_packet_merge_param *pkt_merge_param);
 
-int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 *rss_idx, unsigned int init_nch);
+int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 rss_idx, unsigned int init_nch);
 int mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res, u32 rss_idx);
 int mlx5e_rx_res_rss_cnt(struct mlx5e_rx_res *res);
 int mlx5e_rx_res_rss_index(struct mlx5e_rx_res *res, struct mlx5e_rss *rss);
index 995eedf7a51a03002ad9d407d1fabc178669c401..d507366d773e19f408d8248569418f00ebe5cf20 100644 (file)
@@ -1480,61 +1480,121 @@ static u32 mlx5e_get_rxfh_indir_size(struct net_device *netdev)
 static int mlx5e_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh)
 {
        struct mlx5e_priv *priv = netdev_priv(netdev);
-       u32 rss_context = rxfh->rss_context;
        bool symmetric;
-       int err;
 
        mutex_lock(&priv->state_lock);
-       err = mlx5e_rx_res_rss_get_rxfh(priv->rx_res, rss_context,
-                                       rxfh->indir, rxfh->key, &rxfh->hfunc, &symmetric);
+       mlx5e_rx_res_rss_get_rxfh(priv->rx_res, 0, rxfh->indir, rxfh->key,
+                                 &rxfh->hfunc, &symmetric);
        mutex_unlock(&priv->state_lock);
 
-       if (err)
-               return err;
-
        if (symmetric)
                rxfh->input_xfrm = RXH_XFRM_SYM_OR_XOR;
 
        return 0;
 }
 
-static int mlx5e_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
-                         struct netlink_ext_ack *extack)
+static int mlx5e_rxfh_hfunc_check(struct mlx5e_priv *priv,
+                                 const struct ethtool_rxfh_param *rxfh)
 {
-       bool symmetric = rxfh->input_xfrm == RXH_XFRM_SYM_OR_XOR;
-       struct mlx5e_priv *priv = netdev_priv(dev);
-       u32 *rss_context = &rxfh->rss_context;
-       u8 hfunc = rxfh->hfunc;
        unsigned int count;
-       int err;
-
-       mutex_lock(&priv->state_lock);
 
        count = priv->channels.params.num_channels;
 
-       if (hfunc == ETH_RSS_HASH_XOR) {
+       if (rxfh->hfunc == ETH_RSS_HASH_XOR) {
                unsigned int xor8_max_channels = mlx5e_rqt_max_num_channels_allowed_for_xor8();
 
                if (count > xor8_max_channels) {
-                       err = -EINVAL;
                        netdev_err(priv->netdev, "%s: Cannot set RSS hash function to XOR, current number of channels (%d) exceeds the maximum allowed for XOR8 RSS hfunc (%d)\n",
                                   __func__, count, xor8_max_channels);
-                       goto unlock;
+                       return -EINVAL;
                }
        }
 
-       if (*rss_context && rxfh->rss_delete) {
-               err = mlx5e_rx_res_rss_destroy(priv->rx_res, *rss_context);
+       return 0;
+}
+
+static int mlx5e_set_rxfh(struct net_device *dev,
+                         struct ethtool_rxfh_param *rxfh,
+                         struct netlink_ext_ack *extack)
+{
+       bool symmetric = rxfh->input_xfrm == RXH_XFRM_SYM_OR_XOR;
+       struct mlx5e_priv *priv = netdev_priv(dev);
+       u8 hfunc = rxfh->hfunc;
+       int err;
+
+       mutex_lock(&priv->state_lock);
+
+       err = mlx5e_rxfh_hfunc_check(priv, rxfh);
+       if (err)
                goto unlock;
-       }
 
-       if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
-               err = mlx5e_rx_res_rss_init(priv->rx_res, rss_context, count);
-               if (err)
-                       goto unlock;
-       }
+       err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, rxfh->rss_context,
+                                       rxfh->indir, rxfh->key,
+                                       hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc,
+                                       rxfh->input_xfrm == RXH_XFRM_NO_CHANGE ? NULL : &symmetric);
+
+unlock:
+       mutex_unlock(&priv->state_lock);
+       return err;
+}
+
+static int mlx5e_create_rxfh_context(struct net_device *dev,
+                                    struct ethtool_rxfh_context *ctx,
+                                    const struct ethtool_rxfh_param *rxfh,
+                                    struct netlink_ext_ack *extack)
+{
+       bool symmetric = rxfh->input_xfrm == RXH_XFRM_SYM_OR_XOR;
+       struct mlx5e_priv *priv = netdev_priv(dev);
+       u8 hfunc = rxfh->hfunc;
+       int err;
+
+       mutex_lock(&priv->state_lock);
+
+       err = mlx5e_rxfh_hfunc_check(priv, rxfh);
+       if (err)
+               goto unlock;
+
+       err = mlx5e_rx_res_rss_init(priv->rx_res, rxfh->rss_context,
+                                   priv->channels.params.num_channels);
+       if (err)
+               goto unlock;
+
+       err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, rxfh->rss_context,
+                                       rxfh->indir, rxfh->key,
+                                       hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc,
+                                       rxfh->input_xfrm == RXH_XFRM_NO_CHANGE ? NULL : &symmetric);
+       if (err)
+               goto unlock;
+
+       mlx5e_rx_res_rss_get_rxfh(priv->rx_res, rxfh->rss_context,
+                                 ethtool_rxfh_context_indir(ctx),
+                                 ethtool_rxfh_context_key(ctx),
+                                 &ctx->hfunc, &symmetric);
+       if (symmetric)
+               ctx->input_xfrm = RXH_XFRM_SYM_OR_XOR;
+
+unlock:
+       mutex_unlock(&priv->state_lock);
+       return err;
+}
 
-       err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, *rss_context,
+static int mlx5e_modify_rxfh_context(struct net_device *dev,
+                                    struct ethtool_rxfh_context *ctx,
+                                    const struct ethtool_rxfh_param *rxfh,
+                                    struct netlink_ext_ack *extack)
+{
+       bool symmetric = rxfh->input_xfrm == RXH_XFRM_SYM_OR_XOR;
+       struct mlx5e_priv *priv = netdev_priv(dev);
+       u8 hfunc = rxfh->hfunc;
+       int err;
+
+       mutex_lock(&priv->state_lock);
+
+       err = mlx5e_rxfh_hfunc_check(priv, rxfh);
+       if (err)
+               goto unlock;
+
+       err = mlx5e_rx_res_rss_set_rxfh(priv->rx_res, rxfh->rss_context,
                                        rxfh->indir, rxfh->key,
                                        hfunc == ETH_RSS_HASH_NO_CHANGE ? NULL : &hfunc,
                                        rxfh->input_xfrm == RXH_XFRM_NO_CHANGE ? NULL : &symmetric);
@@ -1544,6 +1604,20 @@ unlock:
        return err;
 }
 
+static int mlx5e_remove_rxfh_context(struct net_device *dev,
+                                    struct ethtool_rxfh_context *ctx,
+                                    u32 rss_context,
+                                    struct netlink_ext_ack *extack)
+{
+       struct mlx5e_priv *priv = netdev_priv(dev);
+       int err;
+
+       mutex_lock(&priv->state_lock);
+       err = mlx5e_rx_res_rss_destroy(priv->rx_res, rss_context);
+       mutex_unlock(&priv->state_lock);
+       return err;
+}
+
 #define MLX5E_PFC_PREVEN_AUTO_TOUT_MSEC                100
 #define MLX5E_PFC_PREVEN_TOUT_MAX_MSEC         8000
 #define MLX5E_PFC_PREVEN_MINOR_PRECENT         85
@@ -2654,9 +2728,9 @@ static void mlx5e_get_ts_stats(struct net_device *netdev,
 
 const struct ethtool_ops mlx5e_ethtool_ops = {
        .cap_link_lanes_supported = true,
-       .cap_rss_ctx_supported  = true,
        .rxfh_per_ctx_fields    = true,
        .rxfh_per_ctx_key       = true,
+       .rxfh_max_num_contexts  = MLX5E_MAX_NUM_RSS,
        .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
                                     ETHTOOL_COALESCE_MAX_FRAMES |
                                     ETHTOOL_COALESCE_USE_ADAPTIVE |
@@ -2685,6 +2759,9 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
        .set_rxfh          = mlx5e_set_rxfh,
        .get_rxfh_fields   = mlx5e_get_rxfh_fields,
        .set_rxfh_fields   = mlx5e_set_rxfh_fields,
+       .create_rxfh_context    = mlx5e_create_rxfh_context,
+       .modify_rxfh_context    = mlx5e_modify_rxfh_context,
+       .remove_rxfh_context    = mlx5e_remove_rxfh_context,
        .get_rxnfc         = mlx5e_get_rxnfc,
        .set_rxnfc         = mlx5e_set_rxnfc,
        .get_tunable       = mlx5e_get_tunable,