mirror of https://github.com/torvalds/linux.git
net: ethtool: add get_rx_ring_count callback to optimize RX ring queries
Add a new optional get_rx_ring_count callback in ethtool_ops to allow drivers to provide the number of RX rings directly without going through the full get_rxnfc flow classification interface. Create ethtool_get_rx_ring_count() to use .get_rx_ring_count if available, falling back to get_rxnfc() otherwise. It needs to be non-static, given it will be called by other ethtool functions laters, as those calling get_rxfh(). Signed-off-by: Breno Leitao <leitao@debian.org> Link: https://patch.msgid.link/20250917-gxrings-v4-4-dae520e2e1cb@debian.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
87c76c2db0
commit
84eaf4359c
|
|
@ -968,6 +968,7 @@ struct kernel_ethtool_ts_info {
|
|||
* @reset: Reset (part of) the device, as specified by a bitmask of
|
||||
* flags from &enum ethtool_reset_flags. Returns a negative
|
||||
* error code or zero.
|
||||
* @get_rx_ring_count: Return the number of RX rings
|
||||
* @get_rxfh_key_size: Get the size of the RX flow hash key.
|
||||
* Returns zero if not supported for this specific device.
|
||||
* @get_rxfh_indir_size: Get the size of the RX flow hash indirection table.
|
||||
|
|
@ -1162,6 +1163,7 @@ struct ethtool_ops {
|
|||
int (*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *);
|
||||
int (*flash_device)(struct net_device *, struct ethtool_flash *);
|
||||
int (*reset)(struct net_device *, u32 *);
|
||||
u32 (*get_rx_ring_count)(struct net_device *dev);
|
||||
u32 (*get_rxfh_key_size)(struct net_device *);
|
||||
u32 (*get_rxfh_indir_size)(struct net_device *);
|
||||
int (*get_rxfh)(struct net_device *, struct ethtool_rxfh_param *);
|
||||
|
|
|
|||
|
|
@ -577,6 +577,26 @@ int __ethtool_get_link(struct net_device *dev)
|
|||
return netif_running(dev) && dev->ethtool_ops->get_link(dev);
|
||||
}
|
||||
|
||||
int ethtool_get_rx_ring_count(struct net_device *dev)
|
||||
{
|
||||
const struct ethtool_ops *ops = dev->ethtool_ops;
|
||||
struct ethtool_rxnfc rx_rings = {};
|
||||
int ret;
|
||||
|
||||
if (ops->get_rx_ring_count)
|
||||
return ops->get_rx_ring_count(dev);
|
||||
|
||||
if (!ops->get_rxnfc)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
rx_rings.cmd = ETHTOOL_GRXRINGS;
|
||||
ret = ops->get_rxnfc(dev, &rx_rings, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return rx_rings.data;
|
||||
}
|
||||
|
||||
static int ethtool_get_rxnfc_rule_count(struct net_device *dev)
|
||||
{
|
||||
const struct ethtool_ops *ops = dev->ethtool_ops;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ void ethtool_ringparam_get_cfg(struct net_device *dev,
|
|||
struct kernel_ethtool_ringparam *kparam,
|
||||
struct netlink_ext_ack *extack);
|
||||
|
||||
int ethtool_get_rx_ring_count(struct net_device *dev);
|
||||
|
||||
int __ethtool_get_ts_info(struct net_device *dev, struct kernel_ethtool_ts_info *info);
|
||||
int ethtool_get_ts_info_by_phc(struct net_device *dev,
|
||||
struct kernel_ethtool_ts_info *info,
|
||||
|
|
|
|||
|
|
@ -1212,23 +1212,21 @@ static noinline_for_stack int ethtool_get_rxrings(struct net_device *dev,
|
|||
u32 cmd,
|
||||
void __user *useraddr)
|
||||
{
|
||||
const struct ethtool_ops *ops = dev->ethtool_ops;
|
||||
struct ethtool_rxnfc info;
|
||||
size_t info_size;
|
||||
int ret;
|
||||
|
||||
if (!ops->get_rxnfc)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
info_size = sizeof(info);
|
||||
ret = ethtool_rxnfc_copy_struct(cmd, &info, &info_size, useraddr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ops->get_rxnfc(dev, &info, NULL);
|
||||
ret = ethtool_get_rx_ring_count(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
info.data = ret;
|
||||
|
||||
return ethtool_rxnfc_copy_to_user(useraddr, &info, info_size, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue