1

Merge branch 'ethtool-use-the-rss-context-xarray-in-ring-deactivation-safety-check'

Jakub Kicinski says:

====================
ethtool: use the rss context XArray in ring deactivation safety-check

Now that we have an XArray storing information about all extra
RSS contexts - use it to extend checks already performed using
ethtool_get_max_rxfh_channel().
====================

Link: https://patch.msgid.link/20240710174043.754664-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2024-07-11 14:41:49 -07:00
commit 6937693d75
4 changed files with 44 additions and 19 deletions

View File

@ -171,11 +171,9 @@ ethnl_set_channels(struct ethnl_req_info *req_info, struct genl_info *info)
*/
if (ethtool_get_max_rxnfc_channel(dev, &max_rxnfc_in_use))
max_rxnfc_in_use = 0;
if (!netif_is_rxfh_configured(dev) ||
ethtool_get_max_rxfh_channel(dev, &max_rxfh_in_use))
max_rxfh_in_use = 0;
max_rxfh_in_use = ethtool_get_max_rxfh_channel(dev);
if (channels.combined_count + channels.rx_count <= max_rxfh_in_use) {
GENL_SET_ERR_MSG(info, "requested channel counts are too low for existing indirection table settings");
GENL_SET_ERR_MSG_FMT(info, "requested channel counts are too low for existing indirection table (%d)", max_rxfh_in_use);
return -EINVAL;
}
if (channels.combined_count + channels.rx_count <= max_rxnfc_in_use) {

View File

@ -587,35 +587,64 @@ err_free_info:
return err;
}
int ethtool_get_max_rxfh_channel(struct net_device *dev, u32 *max)
static u32 ethtool_get_max_rss_ctx_channel(struct net_device *dev)
{
struct ethtool_rxfh_context *ctx;
unsigned long context;
u32 max_ring = 0;
mutex_lock(&dev->ethtool->rss_lock);
xa_for_each(&dev->ethtool->rss_ctx, context, ctx) {
u32 i, *tbl;
tbl = ethtool_rxfh_context_indir(ctx);
for (i = 0; i < ctx->indir_size; i++)
max_ring = max(max_ring, tbl[i]);
}
mutex_unlock(&dev->ethtool->rss_lock);
return max_ring;
}
u32 ethtool_get_max_rxfh_channel(struct net_device *dev)
{
struct ethtool_rxfh_param rxfh = {};
u32 dev_size, current_max = 0;
u32 dev_size, current_max;
int ret;
/* While we do track whether RSS context has an indirection
* table explicitly set by the user, no driver looks at that bit.
* Assume drivers won't auto-regenerate the additional tables,
* to be safe.
*/
current_max = ethtool_get_max_rss_ctx_channel(dev);
if (!netif_is_rxfh_configured(dev))
return current_max;
if (!dev->ethtool_ops->get_rxfh_indir_size ||
!dev->ethtool_ops->get_rxfh)
return -EOPNOTSUPP;
return current_max;
dev_size = dev->ethtool_ops->get_rxfh_indir_size(dev);
if (dev_size == 0)
return -EOPNOTSUPP;
return current_max;
rxfh.indir = kcalloc(dev_size, sizeof(rxfh.indir[0]), GFP_USER);
if (!rxfh.indir)
return -ENOMEM;
return U32_MAX;
ret = dev->ethtool_ops->get_rxfh(dev, &rxfh);
if (ret)
goto out;
if (ret) {
current_max = U32_MAX;
goto out_free;
}
while (dev_size--)
current_max = max(current_max, rxfh.indir[dev_size]);
*max = current_max;
out:
out_free:
kfree(rxfh.indir);
return ret;
return current_max;
}
int ethtool_check_ops(const struct ethtool_ops *ops)

View File

@ -42,7 +42,7 @@ int __ethtool_get_link(struct net_device *dev);
bool convert_legacy_settings_to_link_ksettings(
struct ethtool_link_ksettings *link_ksettings,
const struct ethtool_cmd *legacy_settings);
int ethtool_get_max_rxfh_channel(struct net_device *dev, u32 *max);
u32 ethtool_get_max_rxfh_channel(struct net_device *dev);
int ethtool_get_max_rxnfc_channel(struct net_device *dev, u64 *max);
int __ethtool_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info);

View File

@ -2049,9 +2049,7 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev,
* indirection table/rxnfc settings */
if (ethtool_get_max_rxnfc_channel(dev, &max_rxnfc_in_use))
max_rxnfc_in_use = 0;
if (!netif_is_rxfh_configured(dev) ||
ethtool_get_max_rxfh_channel(dev, &max_rxfh_in_use))
max_rxfh_in_use = 0;
max_rxfh_in_use = ethtool_get_max_rxfh_channel(dev);
if (channels.combined_count + channels.rx_count <=
max_t(u64, max_rxnfc_in_use, max_rxfh_in_use))
return -EINVAL;