[bug report] scsi: mpt3sas: Reload SBR without rebooting HBA

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Ranjan Kumar,

The patch 2c6ebf96dfdf: "scsi: mpt3sas: Reload SBR without rebooting
HBA" from Feb 8, 2023, leads to the following Smatch static checker
warning:

	drivers/scsi/mpt3sas/mpt3sas_base.c:8071 _base_diag_reset()
	error: double unlocked '&ioc->hostdiag_unlock_mutex' (orig line 8005)

drivers/scsi/mpt3sas/mpt3sas_base.c
  7989  static int
  7990  _base_diag_reset(struct MPT3SAS_ADAPTER *ioc)
  7991  {
  7992          u32 host_diagnostic;
  7993          u32 ioc_state;
  7994          u32 count;
  7995          u32 hcb_size;
  7996  
  7997          ioc_info(ioc, "sending diag reset !!\n");
  7998  
  7999          pci_cfg_access_lock(ioc->pdev);
  8000  
  8001          drsprintk(ioc, ioc_info(ioc, "clear interrupts\n"));
  8002  
  8003          mutex_lock(&ioc->hostdiag_unlock_mutex);
  8004          if (mpt3sas_base_unlock_and_get_host_diagnostic(ioc, &host_diagnostic)) {
  8005                  mutex_unlock(&ioc->hostdiag_unlock_mutex);
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Unlock.

  8006                  goto out;
  8007          }
  8008  
  8009          hcb_size = ioc->base_readl(&ioc->chip->HCBSize);
  8010  
  8011          drsprintk(ioc, ioc_info(ioc, "diag reset: issued\n"));
  8012          writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER,
  8013               &ioc->chip->HostDiagnostic);
  8014  
  8015          /*This delay allows the chip PCIe hardware time to finish reset tasks*/
  8016          msleep(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000);
  8017  
  8018          /* Approximately 300 second max wait */
  8019          for (count = 0; count < (300000000 /
  8020                  MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC); count++) {
  8021  
  8022                  host_diagnostic = ioc->base_readl(&ioc->chip->HostDiagnostic);
  8023  
  8024                  if (host_diagnostic == 0xFFFFFFFF) {
  8025                          ioc_info(ioc,
  8026                              "Invalid host diagnostic register value\n");
  8027                          _base_dump_reg_set(ioc);
  8028                          goto out;
  8029                  }
  8030                  if (!(host_diagnostic & MPI2_DIAG_RESET_ADAPTER))
  8031                          break;
  8032  
  8033                  msleep(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC / 1000);
  8034          }
  8035  
  8036          if (host_diagnostic & MPI2_DIAG_HCB_MODE) {
  8037  
  8038                  drsprintk(ioc,
  8039                            ioc_info(ioc, "restart the adapter assuming the HCB Address points to good F/W\n"));
  8040                  host_diagnostic &= ~MPI2_DIAG_BOOT_DEVICE_SELECT_MASK;
  8041                  host_diagnostic |= MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW;
  8042                  writel(host_diagnostic, &ioc->chip->HostDiagnostic);
  8043  
  8044                  drsprintk(ioc, ioc_info(ioc, "re-enable the HCDW\n"));
  8045                  writel(hcb_size | MPI2_HCB_SIZE_HCB_ENABLE,
  8046                      &ioc->chip->HCBSize);
  8047          }
  8048  
  8049          drsprintk(ioc, ioc_info(ioc, "restart the adapter\n"));
  8050          writel(host_diagnostic & ~MPI2_DIAG_HOLD_IOC_RESET,
  8051              &ioc->chip->HostDiagnostic);
  8052          mpt3sas_base_lock_host_diagnostic(ioc);
  8053          mutex_unlock(&ioc->hostdiag_unlock_mutex);
  8054  
  8055          drsprintk(ioc, ioc_info(ioc, "Wait for FW to go to the READY state\n"));
  8056          ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, 20);
  8057          if (ioc_state) {
  8058                  ioc_err(ioc, "%s: failed going to ready state (ioc_state=0x%x)\n",
  8059                          __func__, ioc_state);
  8060                  _base_dump_reg_set(ioc);
  8061                  goto out;
  8062          }
  8063  
  8064          pci_cfg_access_unlock(ioc->pdev);
  8065          ioc_info(ioc, "diag reset: SUCCESS\n");
  8066          return 0;
  8067  
  8068   out:
  8069          pci_cfg_access_unlock(ioc->pdev);
  8070          ioc_err(ioc, "diag reset: FAILED\n");
  8071          mutex_unlock(&ioc->hostdiag_unlock_mutex);
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Double unlock.

  8072          return -EFAULT;
  8073  }

regards,
dan carpenter



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux