summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMike Marciniszyn <mike.marciniszyn@intel.com>2016-05-24 12:50:23 -0700
committerDoug Ledford <dledford@redhat.com>2016-05-26 12:21:10 -0400
commit7049de65c9e520886f06d6f9deceaaed5d93fb7c (patch)
treea6830c3cf1d7de51014c16aa3ca2645961cefa95 /drivers
parentbdd8a98ce465df31b07ff6314db9ed31a7c6bb0d (diff)
downloadlinux-stable-7049de65c9e520886f06d6f9deceaaed5d93fb7c.tar.gz
linux-stable-7049de65c9e520886f06d6f9deceaaed5d93fb7c.tar.bz2
linux-stable-7049de65c9e520886f06d6f9deceaaed5d93fb7c.zip
IB/hfi1: Fix hard lockup due to not using save/restore spin lock
Commit b9b06cb6feda ("IB/hfi1: Fix missing lock/unlock in verbs drain callback") added a spin lock. Unfortunately, the new lock code can be called from a base level interrupt state, and an interrupt that can get stacked will attempt to get the same lock. Fix by using the flag save/restore spin lock variation. Cc: stable@vger.kernel.org # 4.6+ Reviewed-by: Sebastian Sanchez <sebastian.sanchez@intel.com> Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/hw/hfi1/qp.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/hfi1/qp.c b/drivers/infiniband/hw/hfi1/qp.c
index 14f889e3655b..1a942ffba4cb 100644
--- a/drivers/infiniband/hw/hfi1/qp.c
+++ b/drivers/infiniband/hw/hfi1/qp.c
@@ -512,6 +512,7 @@ static void iowait_wakeup(struct iowait *wait, int reason)
static void iowait_sdma_drained(struct iowait *wait)
{
struct rvt_qp *qp = iowait_to_qp(wait);
+ unsigned long flags;
/*
* This happens when the send engine notes
@@ -519,12 +520,12 @@ static void iowait_sdma_drained(struct iowait *wait)
* do the flush work until that QP's
* sdma work has finished.
*/
- spin_lock(&qp->s_lock);
+ spin_lock_irqsave(&qp->s_lock, flags);
if (qp->s_flags & RVT_S_WAIT_DMA) {
qp->s_flags &= ~RVT_S_WAIT_DMA;
hfi1_schedule_send(qp);
}
- spin_unlock(&qp->s_lock);
+ spin_unlock_irqrestore(&qp->s_lock, flags);
}
/**