ethtool: Define and apply a default policy for RX flow hash indirection

All drivers that support modification of the RX flow hash indirection
table initialise it in the same way: RX rings are assigned to table
entries in rotation.  Make that default policy explicit by having them
call a ethtool_rxfh_indir_default() function.

In the ethtool core, add support for a zero size value for
ETHTOOL_SRXFHINDIR, which resets the table to this default.

Partly-suggested-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Acked-by: Shreyas N Bhatewara <sbhatewara@vmware.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Ben Hutchings
2011-12-15 13:56:49 +00:00
committed by David S. Miller
parent 7850f63f16
commit 278bc4296b
6 changed files with 47 additions and 20 deletions

View File

@@ -581,31 +581,38 @@ static noinline_for_stack int ethtool_set_rxfh_indir(struct net_device *dev,
sizeof(user_size)))
return -EFAULT;
if (user_size != dev_size)
if (user_size != 0 && user_size != dev_size)
return -EINVAL;
indir = kcalloc(dev_size, sizeof(indir[0]), GFP_USER);
if (!indir)
return -ENOMEM;
if (copy_from_user(indir,
useraddr +
offsetof(struct ethtool_rxfh_indir, ring_index[0]),
dev_size * sizeof(indir[0]))) {
ret = -EFAULT;
goto out;
}
/* Validate ring indices */
rx_rings.cmd = ETHTOOL_GRXRINGS;
ret = dev->ethtool_ops->get_rxnfc(dev, &rx_rings, NULL);
if (ret)
goto out;
for (i = 0; i < dev_size; i++) {
if (indir[i] >= rx_rings.data) {
ret = -EINVAL;
if (user_size == 0) {
for (i = 0; i < dev_size; i++)
indir[i] = ethtool_rxfh_indir_default(i, rx_rings.data);
} else {
if (copy_from_user(indir,
useraddr +
offsetof(struct ethtool_rxfh_indir,
ring_index[0]),
dev_size * sizeof(indir[0]))) {
ret = -EFAULT;
goto out;
}
/* Validate ring indices */
for (i = 0; i < dev_size; i++) {
if (indir[i] >= rx_rings.data) {
ret = -EINVAL;
goto out;
}
}
}
ret = dev->ethtool_ops->set_rxfh_indir(dev, indir);