From 278bc4296bd64ffd1d3913b487dc8a520e423a7a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 15 Dec 2011 13:56:49 +0000 Subject: 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 Signed-off-by: Ben Hutchings Acked-by: Shreyas N Bhatewara Signed-off-by: David S. Miller --- net/core/ethtool.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'net/core') diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 69f71b8..597732c 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -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); -- cgit v1.1