From: Ahmed S. Darwish Date: Thu, 26 Nov 2020 13:29:41 +0000 (+0100) Subject: scsi: qla4xxx: Remove in_interrupt() X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=a93c3835319849f0226b9a7101284aeb60a5ed8e;p=linux.git scsi: qla4xxx: Remove in_interrupt() qla4_82xx_crb_win_lock() spins on a certain hardware state until it's updated. At the end of each spin, if in_interrupt() is true, it does 20 loops of cpu_relax(). Otherwise, it yields the CPU. The in_interrupt() macro is ill-defined as it does not provide what the name suggests, and it does not catch the intended use-case here. qla4_82xx_crb_win_lock() is always invoked with scsi_qla_host::hw_lock acquired, with disabled interrupts. If the caller is in process context, as in qla4_82xx_need_reset_handler(), then in_interrupt() will return false even though it is not allowed to call schedule(). Remove the in_interrupt() check. Change qla4_82xx_crb_win_lock() specification to a purely atomic function. Mark it as static, remove its forward declaration, and move it above its callers. To avoid hammering the PCI bus while spinning, use a 10 micro-second delay instead of cpu_relax(). Link: https://lore.kernel.org/r/20201126132952.2287996-4-bigeasy@linutronix.de Fixes: f4f5df23bf72 ("[SCSI] qla4xxx: Added support for ISP82XX") Cc: Nilesh Javali Cc: Manish Rangankar Cc: Reviewed-by: Daniel Wagner Signed-off-by: Ahmed S. Darwish Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Martin K. Petersen --- diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index b8f02210aeb03..ea60057b2e20a 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h @@ -114,7 +114,6 @@ irqreturn_t qla4_82xx_intr_handler(int irq, void *dev_id); void qla4_82xx_queue_iocb(struct scsi_qla_host *ha); void qla4_82xx_complete_iocb(struct scsi_qla_host *ha); -int qla4_82xx_crb_win_lock(struct scsi_qla_host *); void qla4_82xx_crb_win_unlock(struct scsi_qla_host *); int qla4_82xx_pci_get_crb_addr_2M(struct scsi_qla_host *, ulong *); void qla4_82xx_wr_32(struct scsi_qla_host *, ulong, u32); diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index f1767b21076f7..da903a545b2c0 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -375,6 +375,35 @@ qla4_82xx_pci_set_crbwindow_2M(struct scsi_qla_host *ha, ulong *off) *off = (*off & MASK(16)) + CRB_INDIRECT_2M + ha->nx_pcibase; } +#define CRB_WIN_LOCK_TIMEOUT 100000000 + +/* + * Context: atomic + */ +static int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha) +{ + int done = 0, timeout = 0; + + while (!done) { + /* acquire semaphore3 from PCI HW block */ + done = qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_LOCK)); + if (done == 1) + break; + if (timeout >= CRB_WIN_LOCK_TIMEOUT) + return -1; + + timeout++; + udelay(10); + } + qla4_82xx_wr_32(ha, QLA82XX_CRB_WIN_LOCK_ID, ha->func_num); + return 0; +} + +void qla4_82xx_crb_win_unlock(struct scsi_qla_host *ha) +{ + qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_UNLOCK)); +} + void qla4_82xx_wr_32(struct scsi_qla_host *ha, ulong off, u32 data) { @@ -475,40 +504,6 @@ int qla4_82xx_md_wr_32(struct scsi_qla_host *ha, uint32_t off, uint32_t data) return rval; } -#define CRB_WIN_LOCK_TIMEOUT 100000000 - -int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha) -{ - int i; - int done = 0, timeout = 0; - - while (!done) { - /* acquire semaphore3 from PCI HW block */ - done = qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_LOCK)); - if (done == 1) - break; - if (timeout >= CRB_WIN_LOCK_TIMEOUT) - return -1; - - timeout++; - - /* Yield CPU */ - if (!in_interrupt()) - schedule(); - else { - for (i = 0; i < 20; i++) - cpu_relax(); /*This a nop instr on i386*/ - } - } - qla4_82xx_wr_32(ha, QLA82XX_CRB_WIN_LOCK_ID, ha->func_num); - return 0; -} - -void qla4_82xx_crb_win_unlock(struct scsi_qla_host *ha) -{ - qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_UNLOCK)); -} - #define IDC_LOCK_TIMEOUT 100000000 /**