diff options
| author | David S. Miller <davem@davemloft.net> | 2018-01-09 11:54:50 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2018-01-09 11:54:50 -0500 |
| commit | a67c01e209356590f5ceaa8be454c6ab4b99c95b (patch) | |
| tree | 8cded4b9519635f9c91fe78641256b4919494519 | |
| parent | 709af180eed51042eeae6c232d109d4c18e88c8e (diff) | |
| parent | bacc7943311e7536a9ef25f06a6cfdea9d228d88 (diff) | |
Merge branch 'ethtool-ringparam-upper-bound'
Tariq Toukan says:
====================
ethtool ringparam upper bound
This patchset by Jenny adds sanity checks in ethtool ringparam
operation for input upper bounds, similarly to what's done in
ethtool_set_channels.
The checks are added in patch 1, using a call to get_ringparam
prior to calling set_ringparam NDO.
Patch 2 changes the function's behavior in mlx4_en, so that
it returns an error for out-of-range input, instead of rounding
it to closest valid, similar to mlx5e.
Patch 3 removes the upper bound checks in mlx5e_ethtool_set_ringparam
as it becomes redundant.
Series generated against net-next commit:
f66faae2f80a Merge branch 'ipv6-ipv4-nexthop-align'
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 17 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 15 | ||||
| -rw-r--r-- | net/core/ethtool.c | 13 |
3 files changed, 24 insertions, 21 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index bf1f04164885..ebc1f566a4d9 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | |||
| @@ -1094,12 +1094,21 @@ static int mlx4_en_set_ringparam(struct net_device *dev, | |||
| 1094 | if (param->rx_jumbo_pending || param->rx_mini_pending) | 1094 | if (param->rx_jumbo_pending || param->rx_mini_pending) |
| 1095 | return -EINVAL; | 1095 | return -EINVAL; |
| 1096 | 1096 | ||
| 1097 | if (param->rx_pending < MLX4_EN_MIN_RX_SIZE) { | ||
| 1098 | en_warn(priv, "%s: rx_pending (%d) < min (%d)\n", | ||
| 1099 | __func__, param->rx_pending, | ||
| 1100 | MLX4_EN_MIN_RX_SIZE); | ||
| 1101 | return -EINVAL; | ||
| 1102 | } | ||
| 1103 | if (param->tx_pending < MLX4_EN_MIN_TX_SIZE) { | ||
| 1104 | en_warn(priv, "%s: tx_pending (%d) < min (%lu)\n", | ||
| 1105 | __func__, param->tx_pending, | ||
| 1106 | MLX4_EN_MIN_TX_SIZE); | ||
| 1107 | return -EINVAL; | ||
| 1108 | } | ||
| 1109 | |||
| 1097 | rx_size = roundup_pow_of_two(param->rx_pending); | 1110 | rx_size = roundup_pow_of_two(param->rx_pending); |
| 1098 | rx_size = max_t(u32, rx_size, MLX4_EN_MIN_RX_SIZE); | ||
| 1099 | rx_size = min_t(u32, rx_size, MLX4_EN_MAX_RX_SIZE); | ||
| 1100 | tx_size = roundup_pow_of_two(param->tx_pending); | 1111 | tx_size = roundup_pow_of_two(param->tx_pending); |
| 1101 | tx_size = max_t(u32, tx_size, MLX4_EN_MIN_TX_SIZE); | ||
| 1102 | tx_size = min_t(u32, tx_size, MLX4_EN_MAX_TX_SIZE); | ||
| 1103 | 1112 | ||
| 1104 | if (rx_size == (priv->port_up ? priv->rx_ring[0]->actual_size : | 1113 | if (rx_size == (priv->port_up ? priv->rx_ring[0]->actual_size : |
| 1105 | priv->rx_ring[0]->size) && | 1114 | priv->rx_ring[0]->size) && |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 8f05efa5c829..1554780d1810 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | |||
| @@ -296,7 +296,6 @@ int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv, | |||
| 296 | struct mlx5e_channels new_channels = {}; | 296 | struct mlx5e_channels new_channels = {}; |
| 297 | u32 rx_pending_wqes; | 297 | u32 rx_pending_wqes; |
| 298 | u32 min_rq_size; | 298 | u32 min_rq_size; |
| 299 | u32 max_rq_size; | ||
| 300 | u8 log_rq_size; | 299 | u8 log_rq_size; |
| 301 | u8 log_sq_size; | 300 | u8 log_sq_size; |
| 302 | u32 num_mtts; | 301 | u32 num_mtts; |
| @@ -315,8 +314,6 @@ int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv, | |||
| 315 | 314 | ||
| 316 | min_rq_size = mlx5e_rx_wqes_to_packets(priv, rq_wq_type, | 315 | min_rq_size = mlx5e_rx_wqes_to_packets(priv, rq_wq_type, |
| 317 | 1 << mlx5_min_log_rq_size(rq_wq_type)); | 316 | 1 << mlx5_min_log_rq_size(rq_wq_type)); |
| 318 | max_rq_size = mlx5e_rx_wqes_to_packets(priv, rq_wq_type, | ||
| 319 | 1 << mlx5_max_log_rq_size(rq_wq_type)); | ||
| 320 | rx_pending_wqes = mlx5e_packets_to_rx_wqes(priv, rq_wq_type, | 317 | rx_pending_wqes = mlx5e_packets_to_rx_wqes(priv, rq_wq_type, |
| 321 | param->rx_pending); | 318 | param->rx_pending); |
| 322 | 319 | ||
| @@ -326,12 +323,6 @@ int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv, | |||
| 326 | min_rq_size); | 323 | min_rq_size); |
| 327 | return -EINVAL; | 324 | return -EINVAL; |
| 328 | } | 325 | } |
| 329 | if (param->rx_pending > max_rq_size) { | ||
| 330 | netdev_info(priv->netdev, "%s: rx_pending (%d) > max (%d)\n", | ||
| 331 | __func__, param->rx_pending, | ||
| 332 | max_rq_size); | ||
| 333 | return -EINVAL; | ||
| 334 | } | ||
| 335 | 326 | ||
| 336 | num_mtts = MLX5E_REQUIRED_MTTS(rx_pending_wqes); | 327 | num_mtts = MLX5E_REQUIRED_MTTS(rx_pending_wqes); |
| 337 | if (priv->channels.params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ && | 328 | if (priv->channels.params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ && |
| @@ -347,12 +338,6 @@ int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv, | |||
| 347 | 1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE); | 338 | 1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE); |
| 348 | return -EINVAL; | 339 | return -EINVAL; |
| 349 | } | 340 | } |
| 350 | if (param->tx_pending > (1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE)) { | ||
| 351 | netdev_info(priv->netdev, "%s: tx_pending (%d) > max (%d)\n", | ||
| 352 | __func__, param->tx_pending, | ||
| 353 | 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE); | ||
| 354 | return -EINVAL; | ||
| 355 | } | ||
| 356 | 341 | ||
| 357 | log_rq_size = order_base_2(rx_pending_wqes); | 342 | log_rq_size = order_base_2(rx_pending_wqes); |
| 358 | log_sq_size = order_base_2(param->tx_pending); | 343 | log_sq_size = order_base_2(param->tx_pending); |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index fff6314f4c5e..107b122c8969 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
| @@ -1693,14 +1693,23 @@ static int ethtool_get_ringparam(struct net_device *dev, void __user *useraddr) | |||
| 1693 | 1693 | ||
| 1694 | static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr) | 1694 | static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr) |
| 1695 | { | 1695 | { |
| 1696 | struct ethtool_ringparam ringparam; | 1696 | struct ethtool_ringparam ringparam, max = { .cmd = ETHTOOL_GRINGPARAM }; |
| 1697 | 1697 | ||
| 1698 | if (!dev->ethtool_ops->set_ringparam) | 1698 | if (!dev->ethtool_ops->set_ringparam || !dev->ethtool_ops->get_ringparam) |
| 1699 | return -EOPNOTSUPP; | 1699 | return -EOPNOTSUPP; |
| 1700 | 1700 | ||
| 1701 | if (copy_from_user(&ringparam, useraddr, sizeof(ringparam))) | 1701 | if (copy_from_user(&ringparam, useraddr, sizeof(ringparam))) |
| 1702 | return -EFAULT; | 1702 | return -EFAULT; |
| 1703 | 1703 | ||
| 1704 | dev->ethtool_ops->get_ringparam(dev, &max); | ||
| 1705 | |||
| 1706 | /* ensure new ring parameters are within the maximums */ | ||
| 1707 | if (ringparam.rx_pending > max.rx_max_pending || | ||
| 1708 | ringparam.rx_mini_pending > max.rx_mini_max_pending || | ||
| 1709 | ringparam.rx_jumbo_pending > max.rx_jumbo_max_pending || | ||
| 1710 | ringparam.tx_pending > max.tx_max_pending) | ||
| 1711 | return -EINVAL; | ||
| 1712 | |||
| 1704 | return dev->ethtool_ops->set_ringparam(dev, &ringparam); | 1713 | return dev->ethtool_ops->set_ringparam(dev, &ringparam); |
| 1705 | } | 1714 | } |
| 1706 | 1715 | ||
