cxgb4: fix possible deadlock
authorGanesh Goudar <ganeshgr@chelsio.com>
Thu, 25 Jan 2018 07:59:43 +0000 (13:29 +0530)
committerDavid S. Miller <davem@davemloft.net>
Thu, 25 Jan 2018 21:30:54 +0000 (16:30 -0500)
t4_wr_mbox_meat_timeout() can be called from both softirq
context and process context, hence protect the mbox with
spin_lock_bh() instead of simple spin_lock()

Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c

index 3405547..af27d2b 100644 (file)
@@ -317,9 +317,9 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
         * wait [for a while] till we're at the front [or bail out with an
         * EBUSY] ...
         */
-       spin_lock(&adap->mbox_lock);
+       spin_lock_bh(&adap->mbox_lock);
        list_add_tail(&entry.list, &adap->mlist.list);
-       spin_unlock(&adap->mbox_lock);
+       spin_unlock_bh(&adap->mbox_lock);
 
        delay_idx = 0;
        ms = delay[0];
@@ -332,9 +332,9 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
                 */
                pcie_fw = t4_read_reg(adap, PCIE_FW_A);
                if (i > FW_CMD_MAX_TIMEOUT || (pcie_fw & PCIE_FW_ERR_F)) {
-                       spin_lock(&adap->mbox_lock);
+                       spin_lock_bh(&adap->mbox_lock);
                        list_del(&entry.list);
-                       spin_unlock(&adap->mbox_lock);
+                       spin_unlock_bh(&adap->mbox_lock);
                        ret = (pcie_fw & PCIE_FW_ERR_F) ? -ENXIO : -EBUSY;
                        t4_record_mbox(adap, cmd, size, access, ret);
                        return ret;
@@ -365,9 +365,9 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
        for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++)
                v = MBOWNER_G(t4_read_reg(adap, ctl_reg));
        if (v != MBOX_OWNER_DRV) {
-               spin_lock(&adap->mbox_lock);
+               spin_lock_bh(&adap->mbox_lock);
                list_del(&entry.list);
-               spin_unlock(&adap->mbox_lock);
+               spin_unlock_bh(&adap->mbox_lock);
                ret = (v == MBOX_OWNER_FW) ? -EBUSY : -ETIMEDOUT;
                t4_record_mbox(adap, cmd, size, access, ret);
                return ret;
@@ -418,9 +418,9 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
                        execute = i + ms;
                        t4_record_mbox(adap, cmd_rpl,
                                       MBOX_LEN, access, execute);
-                       spin_lock(&adap->mbox_lock);
+                       spin_lock_bh(&adap->mbox_lock);
                        list_del(&entry.list);
-                       spin_unlock(&adap->mbox_lock);
+                       spin_unlock_bh(&adap->mbox_lock);
                        return -FW_CMD_RETVAL_G((int)res);
                }
        }
@@ -430,9 +430,9 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
        dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n",
                *(const u8 *)cmd, mbox);
        t4_report_fw_error(adap);
-       spin_lock(&adap->mbox_lock);
+       spin_lock_bh(&adap->mbox_lock);
        list_del(&entry.list);
-       spin_unlock(&adap->mbox_lock);
+       spin_unlock_bh(&adap->mbox_lock);
        t4_fatal_err(adap);
        return ret;
 }