Skip to content

Commit db10fde

Browse files
committed
net: ethtool: fix ioctl confusing drivers about desired HDS user config
The legacy ioctl path does not have support for extended attributes. So we issue a GET to fetch the current settings from the driver, in an attempt to keep them unchanged. HDS is a bit "special" as the GET only returns on/off while the SET takes a "ternary" argument (on/off/default). If the driver was in the "default" setting - executing the ioctl path binds it to on or off, even tho the user did not intend to change HDS config. Factor the relevant logic out of the netlink code and reuse it. Fixes: 87c8f84 ("bnxt_en: add support for tcp-data-split ethtool command") Acked-by: Stanislav Fomichev <[email protected]> Tested-by: Daniel Xu <[email protected]> Tested-by: Taehee Yoo <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent f15176b commit db10fde

File tree

4 files changed

+28
-7
lines changed

4 files changed

+28
-7
lines changed

net/ethtool/common.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <linux/rtnetlink.h>
77
#include <linux/ptp_clock_kernel.h>
88
#include <linux/phy_link_topology.h>
9+
#include <net/netdev_queues.h>
910

1011
#include "netlink.h"
1112
#include "common.h"
@@ -771,6 +772,21 @@ int ethtool_check_ops(const struct ethtool_ops *ops)
771772
return 0;
772773
}
773774

775+
void ethtool_ringparam_get_cfg(struct net_device *dev,
776+
struct ethtool_ringparam *param,
777+
struct kernel_ethtool_ringparam *kparam,
778+
struct netlink_ext_ack *extack)
779+
{
780+
memset(param, 0, sizeof(*param));
781+
memset(kparam, 0, sizeof(*kparam));
782+
783+
param->cmd = ETHTOOL_GRINGPARAM;
784+
dev->ethtool_ops->get_ringparam(dev, param, kparam, extack);
785+
786+
/* Driver gives us current state, we want to return current config */
787+
kparam->tcp_data_split = dev->cfg->hds_config;
788+
}
789+
774790
static void ethtool_init_tsinfo(struct kernel_ethtool_ts_info *info)
775791
{
776792
memset(info, 0, sizeof(*info));

net/ethtool/common.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ int ethtool_check_max_channel(struct net_device *dev,
5151
struct ethtool_channels channels,
5252
struct genl_info *info);
5353
int ethtool_check_rss_ctx_busy(struct net_device *dev, u32 rss_context);
54+
55+
void ethtool_ringparam_get_cfg(struct net_device *dev,
56+
struct ethtool_ringparam *param,
57+
struct kernel_ethtool_ringparam *kparam,
58+
struct netlink_ext_ack *extack);
59+
5460
int __ethtool_get_ts_info(struct net_device *dev, struct kernel_ethtool_ts_info *info);
5561
int ethtool_get_ts_info_by_phc(struct net_device *dev,
5662
struct kernel_ethtool_ts_info *info,

net/ethtool/ioctl.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2059,8 +2059,8 @@ static int ethtool_get_ringparam(struct net_device *dev, void __user *useraddr)
20592059

20602060
static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr)
20612061
{
2062-
struct ethtool_ringparam ringparam, max = { .cmd = ETHTOOL_GRINGPARAM };
20632062
struct kernel_ethtool_ringparam kernel_ringparam;
2063+
struct ethtool_ringparam ringparam, max;
20642064
int ret;
20652065

20662066
if (!dev->ethtool_ops->set_ringparam || !dev->ethtool_ops->get_ringparam)
@@ -2069,7 +2069,7 @@ static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr)
20692069
if (copy_from_user(&ringparam, useraddr, sizeof(ringparam)))
20702070
return -EFAULT;
20712071

2072-
dev->ethtool_ops->get_ringparam(dev, &max, &kernel_ringparam, NULL);
2072+
ethtool_ringparam_get_cfg(dev, &max, &kernel_ringparam, NULL);
20732073

20742074
/* ensure new ring parameters are within the maximums */
20752075
if (ringparam.rx_pending > max.rx_max_pending ||

net/ethtool/rings.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,17 +215,16 @@ ethnl_set_rings_validate(struct ethnl_req_info *req_info,
215215
static int
216216
ethnl_set_rings(struct ethnl_req_info *req_info, struct genl_info *info)
217217
{
218-
struct kernel_ethtool_ringparam kernel_ringparam = {};
219-
struct ethtool_ringparam ringparam = {};
218+
struct kernel_ethtool_ringparam kernel_ringparam;
220219
struct net_device *dev = req_info->dev;
220+
struct ethtool_ringparam ringparam;
221221
struct nlattr **tb = info->attrs;
222222
const struct nlattr *err_attr;
223223
bool mod = false;
224224
int ret;
225225

226-
dev->ethtool_ops->get_ringparam(dev, &ringparam,
227-
&kernel_ringparam, info->extack);
228-
kernel_ringparam.tcp_data_split = dev->cfg->hds_config;
226+
ethtool_ringparam_get_cfg(dev, &ringparam, &kernel_ringparam,
227+
info->extack);
229228

230229
ethnl_update_u32(&ringparam.rx_pending, tb[ETHTOOL_A_RINGS_RX], &mod);
231230
ethnl_update_u32(&ringparam.rx_mini_pending,

0 commit comments

Comments
 (0)