Skip to content

Commit 8036e90

Browse files
Parvi Kaustubhijgunthorpe
authored andcommitted
IB/usnic: Fix potential deadlock
Acquiring the rtnl lock while holding usdev_lock could result in a deadlock. For example: usnic_ib_query_port() | mutex_lock(&us_ibdev->usdev_lock) | ib_get_eth_speed() | rtnl_lock() rtnl_lock() | usnic_ib_netdevice_event() | mutex_lock(&us_ibdev->usdev_lock) This commit moves the usdev_lock acquisition after the rtnl lock has been released. This is safe to do because usdev_lock is not protecting anything being accessed in ib_get_eth_speed(). Hence, the correct order of holding locks (rtnl -> usdev_lock) is not violated. Signed-off-by: Parvi Kaustubhi <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 50c582d commit 8036e90

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

drivers/infiniband/hw/usnic/usnic_ib_verbs.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -336,13 +336,16 @@ int usnic_ib_query_port(struct ib_device *ibdev, u8 port,
336336

337337
usnic_dbg("\n");
338338

339-
mutex_lock(&us_ibdev->usdev_lock);
340339
if (ib_get_eth_speed(ibdev, port, &props->active_speed,
341-
&props->active_width)) {
342-
mutex_unlock(&us_ibdev->usdev_lock);
340+
&props->active_width))
343341
return -EINVAL;
344-
}
345342

343+
/*
344+
* usdev_lock is acquired after (and not before) ib_get_eth_speed call
345+
* because acquiring rtnl_lock in ib_get_eth_speed, while holding
346+
* usdev_lock could lead to a deadlock.
347+
*/
348+
mutex_lock(&us_ibdev->usdev_lock);
346349
/* props being zeroed by the caller, avoid zeroing it here */
347350

348351
props->lid = 0;

0 commit comments

Comments
 (0)