Skip to content

Commit e2dc9b6

Browse files
Michael Chandavem330
authored andcommitted
bnxt_en: Don't use rtnl lock to protect link change logic in workqueue.
As a further improvement to the PF/VF link change logic, use a private mutex instead of the rtnl lock to protect link change logic. With the new mutex, we don't have to take the rtnl lock in the workqueue when we have to handle link related functions. If the VF and PF drivers are running on the same host and both take the rtnl lock and one is waiting for the other, it will cause timeout. This patch fixes these timeouts. Fixes: 90c694b ("bnxt_en: Fix RTNL lock usage on bnxt_update_link().") Signed-off-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c213eae commit e2dc9b6

File tree

3 files changed

+21
-12
lines changed

3 files changed

+21
-12
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6345,7 +6345,9 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
63456345
}
63466346

63476347
if (link_re_init) {
6348+
mutex_lock(&bp->link_lock);
63486349
rc = bnxt_update_phy_setting(bp);
6350+
mutex_unlock(&bp->link_lock);
63496351
if (rc)
63506352
netdev_warn(bp->dev, "failed to update phy settings\n");
63516353
}
@@ -7043,30 +7045,28 @@ static void bnxt_sp_task(struct work_struct *work)
70437045
if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event))
70447046
bnxt_hwrm_port_qstats(bp);
70457047

7046-
/* These functions below will clear BNXT_STATE_IN_SP_TASK. They
7047-
* must be the last functions to be called before exiting.
7048-
*/
70497048
if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) {
7050-
int rc = 0;
7049+
int rc;
70517050

7051+
mutex_lock(&bp->link_lock);
70527052
if (test_and_clear_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT,
70537053
&bp->sp_event))
70547054
bnxt_hwrm_phy_qcaps(bp);
70557055

7056-
bnxt_rtnl_lock_sp(bp);
7057-
if (test_bit(BNXT_STATE_OPEN, &bp->state))
7058-
rc = bnxt_update_link(bp, true);
7059-
bnxt_rtnl_unlock_sp(bp);
7056+
rc = bnxt_update_link(bp, true);
7057+
mutex_unlock(&bp->link_lock);
70607058
if (rc)
70617059
netdev_err(bp->dev, "SP task can't update link (rc: %x)\n",
70627060
rc);
70637061
}
70647062
if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event)) {
7065-
bnxt_rtnl_lock_sp(bp);
7066-
if (test_bit(BNXT_STATE_OPEN, &bp->state))
7067-
bnxt_get_port_module_status(bp);
7068-
bnxt_rtnl_unlock_sp(bp);
7063+
mutex_lock(&bp->link_lock);
7064+
bnxt_get_port_module_status(bp);
7065+
mutex_unlock(&bp->link_lock);
70697066
}
7067+
/* These functions below will clear BNXT_STATE_IN_SP_TASK. They
7068+
* must be the last functions to be called before exiting.
7069+
*/
70707070
if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event))
70717071
bnxt_reset(bp, false);
70727072

@@ -7766,6 +7766,7 @@ static int bnxt_probe_phy(struct bnxt *bp)
77667766
rc);
77677767
return rc;
77687768
}
7769+
mutex_init(&bp->link_lock);
77697770

77707771
rc = bnxt_update_link(bp, false);
77717772
if (rc) {

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,10 @@ struct bnxt {
12901290
unsigned long *ntp_fltr_bmap;
12911291
int ntp_fltr_count;
12921292

1293+
/* To protect link related settings during link changes and
1294+
* ethtool settings changes.
1295+
*/
1296+
struct mutex link_lock;
12931297
struct bnxt_link_info link_info;
12941298
struct ethtool_eee eee;
12951299
u32 lpi_tmr_lo;

drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,7 @@ static int bnxt_get_link_ksettings(struct net_device *dev,
10521052
u32 ethtool_speed;
10531053

10541054
ethtool_link_ksettings_zero_link_mode(lk_ksettings, supported);
1055+
mutex_lock(&bp->link_lock);
10551056
bnxt_fw_to_ethtool_support_spds(link_info, lk_ksettings);
10561057

10571058
ethtool_link_ksettings_zero_link_mode(lk_ksettings, advertising);
@@ -1099,6 +1100,7 @@ static int bnxt_get_link_ksettings(struct net_device *dev,
10991100
base->port = PORT_FIBRE;
11001101
}
11011102
base->phy_address = link_info->phy_addr;
1103+
mutex_unlock(&bp->link_lock);
11021104

11031105
return 0;
11041106
}
@@ -1190,6 +1192,7 @@ static int bnxt_set_link_ksettings(struct net_device *dev,
11901192
if (!BNXT_SINGLE_PF(bp))
11911193
return -EOPNOTSUPP;
11921194

1195+
mutex_lock(&bp->link_lock);
11931196
if (base->autoneg == AUTONEG_ENABLE) {
11941197
BNXT_ETHTOOL_TO_FW_SPDS(fw_advertising, lk_ksettings,
11951198
advertising);
@@ -1234,6 +1237,7 @@ static int bnxt_set_link_ksettings(struct net_device *dev,
12341237
rc = bnxt_hwrm_set_link_setting(bp, set_pause, false);
12351238

12361239
set_setting_exit:
1240+
mutex_unlock(&bp->link_lock);
12371241
return rc;
12381242
}
12391243

0 commit comments

Comments
 (0)