Skip to content

Commit 74828b1

Browse files
skotur-brcmdledford
authored andcommitted
bnxt_re: Remove RTNL lock dependency in bnxt_re_query_port
When there is a NETDEV_UNREGISTER event, bnxt_re driver calls ib_unregister_device() (RTNL lock held). ib_unregister_device attempts to flush a worker queue scheduled by ib_core and that queue might have a pending ib_query_port(). ib_query_port in turn calls bnxt_re_query_port(), which while querying the link speed using ib_get_eth_speed(), tries to acquire the rtnl_lock() which was already held by NETDEV_UNREGISTER. Fixing the issue by removing the link speed query from bnxt_re_query_port() Now the speed is queried post a successful ib_register_device or whenever there is a NETDEV_CHANGE event. Signed-off-by: Somnath Kotur <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent d591730 commit 74828b1

File tree

3 files changed

+9
-8
lines changed

3 files changed

+9
-8
lines changed

drivers/infiniband/hw/bnxt_re/bnxt_re.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ struct bnxt_re_dev {
110110

111111
struct delayed_work worker;
112112
u8 cur_prio_map;
113+
u8 active_speed;
114+
u8 active_width;
113115

114116
/* FP Notification Queue (CQ & SRQ) */
115117
struct tasklet_struct nq_task;

drivers/infiniband/hw/bnxt_re/ib_verbs.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -259,14 +259,9 @@ int bnxt_re_query_port(struct ib_device *ibdev, u8 port_num,
259259
port_attr->sm_sl = 0;
260260
port_attr->subnet_timeout = 0;
261261
port_attr->init_type_reply = 0;
262-
/* call the underlying netdev's ethtool hooks to query speed settings
263-
* for which we acquire rtnl_lock _only_ if it's registered with
264-
* IB stack to avoid race in the NETDEV_UNREG path
265-
*/
266-
if (test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags))
267-
if (ib_get_eth_speed(ibdev, port_num, &port_attr->active_speed,
268-
&port_attr->active_width))
269-
return -EINVAL;
262+
port_attr->active_speed = rdev->active_speed;
263+
port_attr->active_width = rdev->active_width;
264+
270265
return 0;
271266
}
272267

drivers/infiniband/hw/bnxt_re/main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,8 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
11611161
}
11621162
}
11631163
set_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags);
1164+
ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed,
1165+
&rdev->active_width);
11641166
bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, IB_EVENT_PORT_ACTIVE);
11651167
bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, IB_EVENT_GID_CHANGE);
11661168

@@ -1255,6 +1257,8 @@ static void bnxt_re_task(struct work_struct *work)
12551257
else if (netif_carrier_ok(rdev->netdev))
12561258
bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1,
12571259
IB_EVENT_PORT_ACTIVE);
1260+
ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed,
1261+
&rdev->active_width);
12581262
break;
12591263
default:
12601264
break;

0 commit comments

Comments
 (0)