net/mlx5: Take lock with IRQs disabled to avoid deadlock [Linux 5.0]

net/mlx5: Take lock with IRQs disabled to avoid deadlock [Linux 5.0]

This Linux kernel change "net/mlx5: Take lock with IRQs disabled to avoid deadlock" is included in the Linux 5.0 release. This change is authored by Moni Shoua <monis [at]> on Wed Dec 26 19:21:21 2018 +0200. The commit for this change in Linux stable tree is 33814e5 (patch).

net/mlx5: Take lock with IRQs disabled to avoid deadlock

The lock in qp_table might be taken from process context or from
interrupt context. This may lead to a deadlock unless it is taken with
IRQs disabled.

Discovered by lockdep

WARNING: inconsistent lock state
inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W}

python/12572 [HC1[1]:SC0[0]:HE0:SE1] takes:
00000000052a4df4 (&(&table->lock)->rlock#2){?.+.}, /0x50 [mlx5_core]
{HARDIRQ-ON-W} state was registered at:
  mlx5_get_rsc+0x1a/0x50 [mlx5_core]
  mlx5_ib_eqe_pf_action+0x493/0x1be0 [mlx5_ib]
irq event stamp: 103928
hardirqs last  enabled at (103927): [] nk+0x1a/0x1c
hardirqs last disabled at (103928): [] unk+0x1a/0x1c
softirqs last  enabled at (103924): [] tcp_sendmsg+0x31/0x40
softirqs last disabled at (103922): [] 80

other info that might help us debug this:
 Possible unsafe locking scenario:



 *** DEADLOCK ***

Fixes: 032080ab43ac ("IB/mlx5: Lock QP during page fault handling")
Signed-off-by: Moni Shoua <[email protected]>
Reviewed-by: Leon Romanovsky <[email protected]>
Signed-off-by: Saeed Mahameed <[email protected]>

There are 5 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/net/ethernet/mellanox/mlx5/core/qp.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/qp.c b/drivers/net/ethernet/mellanox/mlx5/core/qp.c
index 388f205..370ca94 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/qp.c
@@ -44,14 +44,15 @@
 mlx5_get_rsc(struct mlx5_qp_table *table, u32 rsn)
    struct mlx5_core_rsc_common *common;
+   unsigned long flags;

-   spin_lock(&table->lock);
+   spin_lock_irqsave(&table->lock, flags);

    common = radix_tree_lookup(&table->tree, rsn);
    if (common)

-   spin_unlock(&table->lock);
+   spin_unlock_irqrestore(&table->lock, flags);

    return common;

Leave a Reply

Your email address will not be published. Required fields are marked *