]> git.hungrycats.org Git - linux/commitdiff
IB/hfi1: Fix hard lockup due to not using save/restore spin lock
authorMike Marciniszyn <mike.marciniszyn@intel.com>
Tue, 24 May 2016 19:50:23 +0000 (12:50 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 8 Jun 2016 01:23:43 +0000 (18:23 -0700)
commit 7049de65c9e520886f06d6f9deceaaed5d93fb7c upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/rdma/hfi1/qp.c

index dc9119e1b458ee8117de5520218b216343185ce4..0401955b3b04ac772665311c70fc603f543abdb2 100644 (file)
@@ -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);
 }
 
 /**