Commit b54de559 authored by Edward Cree's avatar Edward Cree Committed by Jakub Kicinski

net: ethtool: fix off-by-one error in max RSS context IDs

Both ethtool_ops.rxfh_max_context_id and the default value used when
 it's not specified are supposed to be exclusive maxima (the former
 is documented as such; the latter, U32_MAX, cannot be used as an ID
 since it equals ETH_RXFH_CONTEXT_ALLOC), but xa_alloc() expects an
 inclusive maximum.
Subtract one from 'limit' to produce an inclusive maximum, and pass
 that to xa_alloc().
Increase bnxt's max by one to prevent a (very minor) regression, as
 BNXT_MAX_ETH_RSS_CTX is an inclusive max.  This is safe since bnxt
 is not actually hard-limited; BNXT_MAX_ETH_RSS_CTX is just a
 leftover from old driver code that managed context IDs itself.
Rename rxfh_max_context_id to rxfh_max_num_contexts to make its
 semantics (hopefully) more obvious.

Fixes: 847a8ab1 ("net: ethtool: let the core choose RSS context IDs")
Signed-off-by: default avatarEdward Cree <ecree.xilinx@gmail.com>
Link: https://patch.msgid.link/5a2d11a599aa5b0cc6141072c01accfb7758650c.1723045898.git.ecree.xilinx@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent a70b637d
...@@ -5290,7 +5290,7 @@ void bnxt_ethtool_free(struct bnxt *bp) ...@@ -5290,7 +5290,7 @@ void bnxt_ethtool_free(struct bnxt *bp)
const struct ethtool_ops bnxt_ethtool_ops = { const struct ethtool_ops bnxt_ethtool_ops = {
.cap_link_lanes_supported = 1, .cap_link_lanes_supported = 1,
.cap_rss_ctx_supported = 1, .cap_rss_ctx_supported = 1,
.rxfh_max_context_id = BNXT_MAX_ETH_RSS_CTX, .rxfh_max_num_contexts = BNXT_MAX_ETH_RSS_CTX + 1,
.rxfh_indir_space = BNXT_MAX_RSS_TABLE_ENTRIES_P5, .rxfh_indir_space = BNXT_MAX_RSS_TABLE_ENTRIES_P5,
.rxfh_priv_size = sizeof(struct bnxt_rss_ctx), .rxfh_priv_size = sizeof(struct bnxt_rss_ctx),
.supported_coalesce_params = ETHTOOL_COALESCE_USECS | .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
......
...@@ -736,10 +736,10 @@ struct kernel_ethtool_ts_info { ...@@ -736,10 +736,10 @@ struct kernel_ethtool_ts_info {
* @rxfh_key_space: same as @rxfh_indir_space, but for the key. * @rxfh_key_space: same as @rxfh_indir_space, but for the key.
* @rxfh_priv_size: size of the driver private data area the core should * @rxfh_priv_size: size of the driver private data area the core should
* allocate for an RSS context (in &struct ethtool_rxfh_context). * allocate for an RSS context (in &struct ethtool_rxfh_context).
* @rxfh_max_context_id: maximum (exclusive) supported RSS context ID. If this * @rxfh_max_num_contexts: maximum (exclusive) supported RSS context ID.
* is zero then the core may choose any (nonzero) ID, otherwise the core * If this is zero then the core may choose any (nonzero) ID, otherwise
* will only use IDs strictly less than this value, as the @rss_context * the core will only use IDs strictly less than this value, as the
* argument to @create_rxfh_context and friends. * @rss_context argument to @create_rxfh_context and friends.
* @supported_coalesce_params: supported types of interrupt coalescing. * @supported_coalesce_params: supported types of interrupt coalescing.
* @supported_ring_params: supported ring params. * @supported_ring_params: supported ring params.
* @get_drvinfo: Report driver/device information. Modern drivers no * @get_drvinfo: Report driver/device information. Modern drivers no
...@@ -954,7 +954,7 @@ struct ethtool_ops { ...@@ -954,7 +954,7 @@ struct ethtool_ops {
u32 rxfh_indir_space; u32 rxfh_indir_space;
u16 rxfh_key_space; u16 rxfh_key_space;
u16 rxfh_priv_size; u16 rxfh_priv_size;
u32 rxfh_max_context_id; u32 rxfh_max_num_contexts;
u32 supported_coalesce_params; u32 supported_coalesce_params;
u32 supported_ring_params; u32 supported_ring_params;
void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *); void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *);
......
...@@ -1449,12 +1449,13 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev, ...@@ -1449,12 +1449,13 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
} }
if (ops->create_rxfh_context) { if (ops->create_rxfh_context) {
u32 limit = ops->rxfh_max_context_id ?: U32_MAX; u32 limit = ops->rxfh_max_num_contexts ?: U32_MAX;
u32 ctx_id; u32 ctx_id;
/* driver uses new API, core allocates ID */ /* driver uses new API, core allocates ID */
ret = xa_alloc(&dev->ethtool->rss_ctx, &ctx_id, ctx, ret = xa_alloc(&dev->ethtool->rss_ctx, &ctx_id, ctx,
XA_LIMIT(1, limit), GFP_KERNEL_ACCOUNT); XA_LIMIT(1, limit - 1),
GFP_KERNEL_ACCOUNT);
if (ret < 0) { if (ret < 0) {
kfree(ctx); kfree(ctx);
goto out; goto out;
......
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