[SCSI] bnx2fc: Avoid holding cq_lock when iounmap() is called
authorBhanu Gollapudi <bprakash@broadcom.com>
Fri, 18 Mar 2011 00:13:26 +0000 (17:13 -0700)
committerJames Bottomley <James.Bottomley@suse.de>
Wed, 23 Mar 2011 16:36:59 +0000 (11:36 -0500)
With kernel debugging enabled, holding cq_lock when calling
bnx2fc_free_session_resc() which calls iounmap() leads to a warning
stack trace [INFO: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected].
iounmap() grabs a HARDIRQ-unsafe vmlist lock, so holding
spin_lock_bh(cq_lock) when calling iounmap() will trigger the LOCKDEP
warning.  Since cq_lock is required only to guard against deletion, hold
the lock just before freeing the cq.

Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com>
Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/bnx2fc/bnx2fc_tgt.c

index 7ea93af..7cc05e4 100644 (file)
@@ -304,10 +304,8 @@ static void bnx2fc_upload_session(struct fcoe_port *port,
                                " not sent to FW\n");
 
        /* Free session resources */
-       spin_lock_bh(&tgt->cq_lock);
        bnx2fc_free_session_resc(hba, tgt);
        bnx2fc_free_conn_id(hba, tgt->fcoe_conn_id);
-       spin_unlock_bh(&tgt->cq_lock);
 }
 
 static int bnx2fc_init_tgt(struct bnx2fc_rport *tgt,
@@ -830,11 +828,13 @@ static void bnx2fc_free_session_resc(struct bnx2fc_hba *hba,
                tgt->rq = NULL;
        }
        /* Free CQ */
+       spin_lock_bh(&tgt->cq_lock);
        if (tgt->cq) {
                dma_free_coherent(&hba->pcidev->dev, tgt->cq_mem_size,
                                    tgt->cq, tgt->cq_dma);
                tgt->cq = NULL;
        }
+       spin_unlock_bh(&tgt->cq_lock);
        /* Free SQ */
        if (tgt->sq) {
                dma_free_coherent(&hba->pcidev->dev, tgt->sq_mem_size,