[PATCH AUTOSEL 4.14 47/73] RDMA/bnxt_re: Fix recursive lock warning in debug kernel

From: Sasha Levin
Date: Wed Oct 31 2018 - 19:10:35 EST


From: Selvin Xavier <selvin.xavier@xxxxxxxxxxxx>

[ Upstream commit d455f29f6d76a5f94881ca1289aaa1e90617ff5d ]

Fix possible recursive lock warning. Its a false warning as the locks are
part of two differnt HW Queue data structure - cmdq and creq. Debug kernel
is throwing the following warning and stack trace.

[ 783.914967] ============================================
[ 783.914970] WARNING: possible recursive locking detected
[ 783.914973] 4.19.0-rc2+ #33 Not tainted
[ 783.914976] --------------------------------------------
[ 783.914979] swapper/2/0 is trying to acquire lock:
[ 783.914982] 000000002aa3949d (&(&hwq->lock)->rlock){..-.}, at: bnxt_qplib_service_creq+0x232/0x350 [bnxt_re]
[ 783.914999]
but task is already holding lock:
[ 783.915002] 00000000be73920d (&(&hwq->lock)->rlock){..-.}, at: bnxt_qplib_service_creq+0x2a/0x350 [bnxt_re]
[ 783.915013]
other info that might help us debug this:
[ 783.915016] Possible unsafe locking scenario:

[ 783.915019] CPU0
[ 783.915021] ----
[ 783.915034] lock(&(&hwq->lock)->rlock);
[ 783.915035] lock(&(&hwq->lock)->rlock);
[ 783.915037]
*** DEADLOCK ***

[ 783.915038] May be due to missing lock nesting notation

[ 783.915039] 1 lock held by swapper/2/0:
[ 783.915040] #0: 00000000be73920d (&(&hwq->lock)->rlock){..-.}, at: bnxt_qplib_service_creq+0x2a/0x350 [bnxt_re]
[ 783.915044]
stack backtrace:
[ 783.915046] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 4.19.0-rc2+ #33
[ 783.915047] Hardware name: Dell Inc. PowerEdge R730/0599V5, BIOS 1.0.4 08/28/2014
[ 783.915048] Call Trace:
[ 783.915049] <IRQ>
[ 783.915054] dump_stack+0x90/0xe3
[ 783.915058] __lock_acquire+0x106c/0x1080
[ 783.915061] ? sched_clock+0x5/0x10
[ 783.915063] lock_acquire+0xbd/0x1a0
[ 783.915065] ? bnxt_qplib_service_creq+0x232/0x350 [bnxt_re]
[ 783.915069] _raw_spin_lock_irqsave+0x4a/0x90
[ 783.915071] ? bnxt_qplib_service_creq+0x232/0x350 [bnxt_re]
[ 783.915073] bnxt_qplib_service_creq+0x232/0x350 [bnxt_re]
[ 783.915078] tasklet_action_common.isra.17+0x197/0x1b0
[ 783.915081] __do_softirq+0xcb/0x3a6
[ 783.915084] irq_exit+0xe9/0x100
[ 783.915085] do_IRQ+0x6a/0x120
[ 783.915087] common_interrupt+0xf/0xf
[ 783.915088] </IRQ>

Use nested notation for the spin_lock to avoid this warning.

Signed-off-by: Selvin Xavier <selvin.xavier@xxxxxxxxxxxx>
Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxxxx>
Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
---
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
index 8d91733009a4..ad74988837c9 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
@@ -311,8 +311,17 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
bnxt_qplib_release_cq_locks(qp, &flags);
break;
default:
- /* Command Response */
- spin_lock_irqsave(&cmdq->lock, flags);
+ /*
+ * Command Response
+ * cmdq->lock needs to be acquired to synchronie
+ * the command send and completion reaping. This function
+ * is always called with creq->lock held. Using
+ * the nested variant of spin_lock.
+ *
+ */
+
+ spin_lock_irqsave_nested(&cmdq->lock, flags,
+ SINGLE_DEPTH_NESTING);
cookie = le16_to_cpu(qp_event->cookie);
mcookie = qp_event->cookie;
blocked = cookie & RCFW_CMD_IS_BLOCKING;
--
2.17.1