]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sif: sif_r3: fix sif_r3_recreate_flush_qp soft lockup.
authorTriviño <francisco.trivino@oracle.com>
Tue, 7 Jun 2016 14:24:20 +0000 (16:24 +0200)
committerKnut Omang <knut.omang@oracle.com>
Sun, 3 Jul 2016 14:01:41 +0000 (16:01 +0200)
This commit fixes Orabug: #23540257. It prevents the situation where
the flush_retry_qp is used before the sdev->flush_lock has been
initialized. This occurs when IB_EVENT_LID_CHANGE event is received
before the flush_retry_qp is created by the driver.

Signed-off-by: Triviño <francisco.trivino@oracle.com>
Reviewed-by: Knut Omang <knut.omang@oracle.com>
drivers/infiniband/hw/sif/sif_main.c
drivers/infiniband/hw/sif/sif_r3.c
drivers/infiniband/hw/sif/sif_r3.h

index b6e0e0e37b63fca85d019faf62e99c39a9e66617..3e33f40d9e166628cd24574db917f1f34ebeae2c 100644 (file)
@@ -313,6 +313,10 @@ static int sif_probe(struct pci_dev *pdev,
        if (err)
                goto pfail_bar;
 
+        /* This must be done before events reception - see Orabug: 23540257 */
+       if (PSIF_REVISION(sdev) <= 3)
+               sif_r3_pre_init(sdev);
+
        if (xen_pv_domain()) {
                /* The Xen PV domain may return huge pages that are misaligned
                 * in DMA space, see Orabug: 21690736.
index 679cc7b9cf25285a720fdbe646c77fec6b2494a8..4b4205de05391cfaf7bf17e8176594301b1e32fc 100644 (file)
@@ -31,6 +31,12 @@ static int outstanding_wqes(struct sif_dev *sdev, struct sif_qp *qp, u16 *head);
 static u16 cq_walk_wa4074(struct sif_dev *sdev, struct sif_qp *qp, bool *last_seq_set);
 static u16 walk_and_update_cqes(struct sif_dev *sdev, struct sif_qp *qp, u16 head, u16 end);
 
+void sif_r3_pre_init(struct sif_dev *sdev)
+{
+       /* Init the flush_retry qp lock */
+       mutex_init(&sdev->flush_lock);
+}
+
 int sif_r3_init(struct sif_dev *sdev)
 {
        int ret;
@@ -46,8 +52,6 @@ int sif_r3_init(struct sif_dev *sdev)
                dne_qp_alloc = true;
        }
 
-       /* Init the flush_retry qp lock */
-       mutex_init(&sdev->flush_lock);
        ret = sif_hw_allocate_flush_qp(sdev);
        if (ret)
                goto flush_retry_failed;
index 6fffc755952f6c5bdacccddd02d0c17e6f594f3c..7086483ac2f85bd33bbc97aac045ca1ddee44207 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef _SIF_R3_H
 #define _SIF_R3_H
 
+void sif_r3_pre_init(struct sif_dev *sdev);
 int sif_r3_init(struct sif_dev *sdev);
 void sif_r3_deinit(struct sif_dev *sdev);