]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
scsi: pmcraid: fix lock imbalance in pmcraid_reset_reload()
authorChristoph Hellwig <hch@lst.de>
Sun, 23 Apr 2017 08:33:23 +0000 (10:33 +0200)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 24 Apr 2017 21:59:50 +0000 (17:59 -0400)
sparse found a bug that has always been present since the driver was
merged:

drivers/scsi/pmcraid.c:2353:12: warning: context imbalance in 'pmcraid_reset_reload' - different lock contexts for basic block

Fix this by using a common unlock goto label, and also reduce the
indentation level in the function.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/pmcraid.c

index 49e70a383afaedf0c56024249b10bd67540169e7..3cc858f45838ada4d1ebe5ec661c23c1138f3e89 100644 (file)
@@ -2373,46 +2373,43 @@ static int pmcraid_reset_reload(
                spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
 
                if (pinstance->ioa_state == IOA_STATE_DEAD) {
-                       spin_unlock_irqrestore(pinstance->host->host_lock,
-                                              lock_flags);
                        pmcraid_info("reset_reload: IOA is dead\n");
-                       return reset;
-               } else if (pinstance->ioa_state == target_state) {
+                       goto out_unlock;
+               }
+
+               if (pinstance->ioa_state == target_state) {
                        reset = 0;
+                       goto out_unlock;
                }
        }
 
-       if (reset) {
-               pmcraid_info("reset_reload: proceeding with reset\n");
-               scsi_block_requests(pinstance->host);
-               reset_cmd = pmcraid_get_free_cmd(pinstance);
-
-               if (reset_cmd == NULL) {
-                       pmcraid_err("no free cmnd for reset_reload\n");
-                       spin_unlock_irqrestore(pinstance->host->host_lock,
-                                              lock_flags);
-                       return reset;
-               }
+       pmcraid_info("reset_reload: proceeding with reset\n");
+       scsi_block_requests(pinstance->host);
+       reset_cmd = pmcraid_get_free_cmd(pinstance);
+       if (reset_cmd == NULL) {
+               pmcraid_err("no free cmnd for reset_reload\n");
+               goto out_unlock;
+       }
 
-               if (shutdown_type == SHUTDOWN_NORMAL)
-                       pinstance->ioa_bringdown = 1;
+       if (shutdown_type == SHUTDOWN_NORMAL)
+               pinstance->ioa_bringdown = 1;
 
-               pinstance->ioa_shutdown_type = shutdown_type;
-               pinstance->reset_cmd = reset_cmd;
-               pinstance->force_ioa_reset = reset;
-               pmcraid_info("reset_reload: initiating reset\n");
-               pmcraid_ioa_reset(reset_cmd);
-               spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
-               pmcraid_info("reset_reload: waiting for reset to complete\n");
-               wait_event(pinstance->reset_wait_q,
-                          !pinstance->ioa_reset_in_progress);
+       pinstance->ioa_shutdown_type = shutdown_type;
+       pinstance->reset_cmd = reset_cmd;
+       pinstance->force_ioa_reset = reset;
+       pmcraid_info("reset_reload: initiating reset\n");
+       pmcraid_ioa_reset(reset_cmd);
+       spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+       pmcraid_info("reset_reload: waiting for reset to complete\n");
+       wait_event(pinstance->reset_wait_q,
+                  !pinstance->ioa_reset_in_progress);
 
-               pmcraid_info("reset_reload: reset is complete !!\n");
-               scsi_unblock_requests(pinstance->host);
-               if (pinstance->ioa_state == target_state)
-                       reset = 0;
-       }
+       pmcraid_info("reset_reload: reset is complete !!\n");
+       scsi_unblock_requests(pinstance->host);
+       return pinstance->ioa_state != target_state;
 
+out_unlock:
+       spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
        return reset;
 }