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:
commit
6937693d75
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user