Skip to content

Commit 4bc71cb

Browse files
Jiri Pirkodavem330
Jiri Pirko
authored andcommitted
net: consolidate and fix ethtool_ops->get_settings calling
This patch does several things: - introduces __ethtool_get_settings which is called from ethtool code and from drivers as well. Put ASSERT_RTNL there. - dev_ethtool_get_settings() is replaced by __ethtool_get_settings() - changes calling in drivers so rtnl locking is respected. In iboe_get_rate was previously ->get_settings() called unlocked. This fixes it. Also prb_calc_retire_blk_tmo() in af_packet.c had the same problem. Also fixed by calling __dev_get_by_index() instead of dev_get_by_index() and holding rtnl_lock for both calls. - introduces rtnl_lock in bnx2fc_vport_create() and fcoe_vport_create() so bnx2fc_if_create() and fcoe_if_create() are called locked as they are from other places. - use __ethtool_get_settings() in bonding code Signed-off-by: Jiri Pirko <[email protected]> v2->v3: -removed dev_ethtool_get_settings() -added ASSERT_RTNL into __ethtool_get_settings() -prb_calc_retire_blk_tmo - use __dev_get_by_index() and lock around it and __ethtool_get_settings() call v1->v2: add missing export_symbol Reviewed-by: Ben Hutchings <[email protected]> [except FCoE bits] Acked-by: Ralf Baechle <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c5dac7c commit 4bc71cb

File tree

14 files changed

+69
-74
lines changed

14 files changed

+69
-74
lines changed

arch/mips/txx9/generic/setup_tx4939.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask)
321321
static u32 tx4939_get_eth_speed(struct net_device *dev)
322322
{
323323
struct ethtool_cmd cmd;
324-
if (dev_ethtool_get_settings(dev, &cmd))
324+
if (__ethtool_get_settings(dev, &cmd))
325325
return 100; /* default 100Mbps */
326326

327327
return ethtool_cmd_speed(&cmd);

drivers/net/bonding/bond_main.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -557,26 +557,23 @@ static int bond_set_carrier(struct bonding *bond)
557557
static int bond_update_speed_duplex(struct slave *slave)
558558
{
559559
struct net_device *slave_dev = slave->dev;
560-
struct ethtool_cmd etool = { .cmd = ETHTOOL_GSET };
560+
struct ethtool_cmd ecmd;
561561
u32 slave_speed;
562562
int res;
563563

564564
/* Fake speed and duplex */
565565
slave->speed = SPEED_100;
566566
slave->duplex = DUPLEX_FULL;
567567

568-
if (!slave_dev->ethtool_ops || !slave_dev->ethtool_ops->get_settings)
569-
return -1;
570-
571-
res = slave_dev->ethtool_ops->get_settings(slave_dev, &etool);
568+
res = __ethtool_get_settings(slave_dev, &ecmd);
572569
if (res < 0)
573570
return -1;
574571

575-
slave_speed = ethtool_cmd_speed(&etool);
572+
slave_speed = ethtool_cmd_speed(&ecmd);
576573
if (slave_speed == 0 || slave_speed == ((__u32) -1))
577574
return -1;
578575

579-
switch (etool.duplex) {
576+
switch (ecmd.duplex) {
580577
case DUPLEX_FULL:
581578
case DUPLEX_HALF:
582579
break;
@@ -585,7 +582,7 @@ static int bond_update_speed_duplex(struct slave *slave)
585582
}
586583

587584
slave->speed = slave_speed;
588-
slave->duplex = etool.duplex;
585+
slave->duplex = ecmd.duplex;
589586

590587
return 0;
591588
}

drivers/net/macvlan.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,8 @@ static int macvlan_ethtool_get_settings(struct net_device *dev,
543543
struct ethtool_cmd *cmd)
544544
{
545545
const struct macvlan_dev *vlan = netdev_priv(dev);
546-
return dev_ethtool_get_settings(vlan->lowerdev, cmd);
546+
547+
return __ethtool_get_settings(vlan->lowerdev, cmd);
547548
}
548549

549550
static const struct ethtool_ops macvlan_ethtool_ops = {

drivers/scsi/bnx2fc/bnx2fc_fcoe.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ static void bnx2fc_link_speed_update(struct fc_lport *lport)
673673
struct net_device *netdev = interface->netdev;
674674
struct ethtool_cmd ecmd;
675675

676-
if (!dev_ethtool_get_settings(netdev, &ecmd)) {
676+
if (!__ethtool_get_settings(netdev, &ecmd)) {
677677
lport->link_supported_speeds &=
678678
~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
679679
if (ecmd.supported & (SUPPORTED_1000baseT_Half |
@@ -1001,9 +1001,11 @@ static int bnx2fc_vport_create(struct fc_vport *vport, bool disabled)
10011001
"this interface\n");
10021002
return -EIO;
10031003
}
1004+
rtnl_lock();
10041005
mutex_lock(&bnx2fc_dev_lock);
10051006
vn_port = bnx2fc_if_create(interface, &vport->dev, 1);
10061007
mutex_unlock(&bnx2fc_dev_lock);
1008+
rtnl_unlock();
10071009

10081010
if (IS_ERR(vn_port)) {
10091011
printk(KERN_ERR PFX "bnx2fc_vport_create (%s) failed\n",

drivers/scsi/fcoe/fcoe.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2043,7 +2043,7 @@ int fcoe_link_speed_update(struct fc_lport *lport)
20432043
struct net_device *netdev = fcoe_netdev(lport);
20442044
struct ethtool_cmd ecmd;
20452045

2046-
if (!dev_ethtool_get_settings(netdev, &ecmd)) {
2046+
if (!__ethtool_get_settings(netdev, &ecmd)) {
20472047
lport->link_supported_speeds &=
20482048
~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
20492049
if (ecmd.supported & (SUPPORTED_1000baseT_Half |
@@ -2452,7 +2452,9 @@ static int fcoe_vport_create(struct fc_vport *vport, bool disabled)
24522452
}
24532453

24542454
mutex_lock(&fcoe_config_mutex);
2455+
rtnl_lock();
24552456
vn_port = fcoe_if_create(fcoe, &vport->dev, 1);
2457+
rtnl_unlock();
24562458
mutex_unlock(&fcoe_config_mutex);
24572459

24582460
if (IS_ERR(vn_port)) {

include/linux/ethtool.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,9 @@ enum ethtool_sfeatures_retval_bits {
728728
/* needed by dev_disable_lro() */
729729
extern int __ethtool_set_flags(struct net_device *dev, u32 flags);
730730

731+
extern int __ethtool_get_settings(struct net_device *dev,
732+
struct ethtool_cmd *cmd);
733+
731734
/**
732735
* enum ethtool_phys_id_state - indicator state for physical identification
733736
* @ETHTOOL_ID_INACTIVE: Physical ID indicator should be deactivated

include/linux/netdevice.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,9 +2589,6 @@ static inline int netif_is_bond_slave(struct net_device *dev)
25892589

25902590
extern struct pernet_operations __net_initdata loopback_net_ops;
25912591

2592-
int dev_ethtool_get_settings(struct net_device *dev,
2593-
struct ethtool_cmd *cmd);
2594-
25952592
static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev)
25962593
{
25972594
if (dev->features & NETIF_F_RXCSUM)

include/rdma/ib_addr.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,12 @@ static inline int iboe_get_rate(struct net_device *dev)
218218
{
219219
struct ethtool_cmd cmd;
220220
u32 speed;
221+
int err;
221222

222-
if (dev_ethtool_get_settings(dev, &cmd))
223+
rtnl_lock();
224+
err = __ethtool_get_settings(dev, &cmd);
225+
rtnl_unlock();
226+
if (err)
223227
return IB_RATE_PORT_CURRENT;
224228

225229
speed = ethtool_cmd_speed(&cmd);

net/8021q/vlan_dev.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,8 @@ static int vlan_ethtool_get_settings(struct net_device *dev,
610610
struct ethtool_cmd *cmd)
611611
{
612612
const struct vlan_dev_info *vlan = vlan_dev_info(dev);
613-
return dev_ethtool_get_settings(vlan->real_dev, cmd);
613+
614+
return __ethtool_get_settings(vlan->real_dev, cmd);
614615
}
615616

616617
static void vlan_ethtool_get_drvinfo(struct net_device *dev,

net/bridge/br_if.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static int port_cost(struct net_device *dev)
3535
{
3636
struct ethtool_cmd ecmd;
3737

38-
if (!dev_ethtool_get_settings(dev, &ecmd)) {
38+
if (!__ethtool_get_settings(dev, &ecmd)) {
3939
switch (ethtool_cmd_speed(&ecmd)) {
4040
case SPEED_10000:
4141
return 2;

net/core/dev.c

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4565,30 +4565,6 @@ void dev_set_rx_mode(struct net_device *dev)
45654565
netif_addr_unlock_bh(dev);
45664566
}
45674567

4568-
/**
4569-
* dev_ethtool_get_settings - call device's ethtool_ops::get_settings()
4570-
* @dev: device
4571-
* @cmd: memory area for ethtool_ops::get_settings() result
4572-
*
4573-
* The cmd arg is initialized properly (cleared and
4574-
* ethtool_cmd::cmd field set to ETHTOOL_GSET).
4575-
*
4576-
* Return device's ethtool_ops::get_settings() result value or
4577-
* -EOPNOTSUPP when device doesn't expose
4578-
* ethtool_ops::get_settings() operation.
4579-
*/
4580-
int dev_ethtool_get_settings(struct net_device *dev,
4581-
struct ethtool_cmd *cmd)
4582-
{
4583-
if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
4584-
return -EOPNOTSUPP;
4585-
4586-
memset(cmd, 0, sizeof(struct ethtool_cmd));
4587-
cmd->cmd = ETHTOOL_GSET;
4588-
return dev->ethtool_ops->get_settings(dev, cmd);
4589-
}
4590-
EXPORT_SYMBOL(dev_ethtool_get_settings);
4591-
45924568
/**
45934569
* dev_get_flags - get flags reported to userspace
45944570
* @dev: device

net/core/ethtool.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -569,15 +569,25 @@ int __ethtool_set_flags(struct net_device *dev, u32 data)
569569
return 0;
570570
}
571571

572-
static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
572+
int __ethtool_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
573573
{
574-
struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
575-
int err;
574+
ASSERT_RTNL();
576575

577-
if (!dev->ethtool_ops->get_settings)
576+
if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
578577
return -EOPNOTSUPP;
579578

580-
err = dev->ethtool_ops->get_settings(dev, &cmd);
579+
memset(cmd, 0, sizeof(struct ethtool_cmd));
580+
cmd->cmd = ETHTOOL_GSET;
581+
return dev->ethtool_ops->get_settings(dev, cmd);
582+
}
583+
EXPORT_SYMBOL(__ethtool_get_settings);
584+
585+
static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
586+
{
587+
int err;
588+
struct ethtool_cmd cmd;
589+
590+
err = __ethtool_get_settings(dev, &cmd);
581591
if (err < 0)
582592
return err;
583593

net/core/net-sysfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ static ssize_t show_speed(struct device *dev,
147147

148148
if (netif_running(netdev)) {
149149
struct ethtool_cmd cmd;
150-
if (!dev_ethtool_get_settings(netdev, &cmd))
150+
if (!__ethtool_get_settings(netdev, &cmd))
151151
ret = sprintf(buf, fmt_udec, ethtool_cmd_speed(&cmd));
152152
}
153153
rtnl_unlock();
@@ -165,7 +165,7 @@ static ssize_t show_duplex(struct device *dev,
165165

166166
if (netif_running(netdev)) {
167167
struct ethtool_cmd cmd;
168-
if (!dev_ethtool_get_settings(netdev, &cmd))
168+
if (!__ethtool_get_settings(netdev, &cmd))
169169
ret = sprintf(buf, "%s\n",
170170
cmd.duplex ? "full" : "half");
171171
}

net/packet/af_packet.c

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -530,33 +530,35 @@ static int prb_calc_retire_blk_tmo(struct packet_sock *po,
530530
{
531531
struct net_device *dev;
532532
unsigned int mbits = 0, msec = 0, div = 0, tmo = 0;
533+
struct ethtool_cmd ecmd;
534+
int err;
533535

534-
dev = dev_get_by_index(sock_net(&po->sk), po->ifindex);
535-
if (unlikely(dev == NULL))
536+
rtnl_lock();
537+
dev = __dev_get_by_index(sock_net(&po->sk), po->ifindex);
538+
if (unlikely(!dev)) {
539+
rtnl_unlock();
536540
return DEFAULT_PRB_RETIRE_TOV;
537-
538-
if (dev->ethtool_ops && dev->ethtool_ops->get_settings) {
539-
struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET, };
540-
541-
if (!dev->ethtool_ops->get_settings(dev, &ecmd)) {
542-
switch (ecmd.speed) {
543-
case SPEED_10000:
544-
msec = 1;
545-
div = 10000/1000;
546-
break;
547-
case SPEED_1000:
548-
msec = 1;
549-
div = 1000/1000;
550-
break;
551-
/*
552-
* If the link speed is so slow you don't really
553-
* need to worry about perf anyways
554-
*/
555-
case SPEED_100:
556-
case SPEED_10:
557-
default:
558-
return DEFAULT_PRB_RETIRE_TOV;
559-
}
541+
}
542+
err = __ethtool_get_settings(dev, &ecmd);
543+
rtnl_unlock();
544+
if (!err) {
545+
switch (ecmd.speed) {
546+
case SPEED_10000:
547+
msec = 1;
548+
div = 10000/1000;
549+
break;
550+
case SPEED_1000:
551+
msec = 1;
552+
div = 1000/1000;
553+
break;
554+
/*
555+
* If the link speed is so slow you don't really
556+
* need to worry about perf anyways
557+
*/
558+
case SPEED_100:
559+
case SPEED_10:
560+
default:
561+
return DEFAULT_PRB_RETIRE_TOV;
560562
}
561563
}
562564

0 commit comments

Comments
 (0)