On Fri, Oct 30, 2020 at 6:59 AM Viswas G <Viswas.G@xxxxxxxxxxxxxxxxx> wrote: > > From: akshatzen <akshatzen@xxxxxxxxxx> > > Today in function check_fw_ready we do busy wait using udelay. Due to > which CPU is not released and we see CPU need_resched failures. > > Here busy waiting is not necessary since we are in process context and > we should sleep instead. So to avoid busy waiting we are replacing > udelay with msleep of 20 ms intervals to check for FW to become ready. > > It's verified that check_fw_ready today is not being used in interrupt > context anywhere, hence it is safe to make this change. > > Tested: > Installed the kernel and looked at dmesg for failures pertaining to > need_resched and did not find them. > > Signed-off-by: akshatzen <akshatzen@xxxxxxxxxx> > Signed-off-by: Viswas G <Viswas.G@xxxxxxxxxxxxx> > Signed-off-by: Ruksar Devadi <Ruksar.devadi@xxxxxxxxxxxxx> > Signed-off-by: Radha Ramachandran <radha@xxxxxxxxxx> Acked-by: Jack Wang <jinpu.wang@xxxxxxxxxxxxxxx> > --- > drivers/scsi/pm8001/pm80xx_hwi.c | 21 +++++++++++---------- > drivers/scsi/pm8001/pm80xx_hwi.h | 6 ++++++ > 2 files changed, 17 insertions(+), 10 deletions(-) > > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c > index 1ba93fb76093..24a4f6b9e79d 100644 > --- a/drivers/scsi/pm8001/pm80xx_hwi.c > +++ b/drivers/scsi/pm8001/pm80xx_hwi.c > @@ -1042,6 +1042,7 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha) > > /** > * check_fw_ready - The LLDD check if the FW is ready, if not, return error. > + * This function sleeps hence it must not be used in atomic context. > * @pm8001_ha: our hba card information > */ > static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) > @@ -1052,16 +1053,16 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) > int ret = 0; > > /* reset / PCIe ready */ > - max_wait_time = max_wait_count = 100 * 1000; /* 100 milli sec */ > + max_wait_time = max_wait_count = 5; /* 100 milli sec */ > do { > - udelay(1); > + msleep(FW_READY_INTERVAL); > value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); > } while ((value == 0xFFFFFFFF) && (--max_wait_count)); > > /* check ila status */ > - max_wait_time = max_wait_count = 1000 * 1000; /* 1000 milli sec */ > + max_wait_time = max_wait_count = 50; /* 1000 milli sec */ > do { > - udelay(1); > + msleep(FW_READY_INTERVAL); > value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); > } while (((value & SCRATCH_PAD_ILA_READY) != > SCRATCH_PAD_ILA_READY) && (--max_wait_count)); > @@ -1074,9 +1075,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) > } > > /* check RAAE status */ > - max_wait_time = max_wait_count = 1800 * 1000; /* 1800 milli sec */ > + max_wait_time = max_wait_count = 90; /* 1800 milli sec */ > do { > - udelay(1); > + msleep(FW_READY_INTERVAL); > value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); > } while (((value & SCRATCH_PAD_RAAE_READY) != > SCRATCH_PAD_RAAE_READY) && (--max_wait_count)); > @@ -1089,9 +1090,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) > } > > /* check iop0 status */ > - max_wait_time = max_wait_count = 600 * 1000; /* 600 milli sec */ > + max_wait_time = max_wait_count = 30; /* 600 milli sec */ > do { > - udelay(1); > + msleep(FW_READY_INTERVAL); > value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); > } while (((value & SCRATCH_PAD_IOP0_READY) != SCRATCH_PAD_IOP0_READY) && > (--max_wait_count)); > @@ -1107,9 +1108,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) > if ((pm8001_ha->chip_id != chip_8008) && > (pm8001_ha->chip_id != chip_8009)) { > /* 200 milli sec */ > - max_wait_time = max_wait_count = 200 * 1000; > + max_wait_time = max_wait_count = 10; > do { > - udelay(1); > + msleep(FW_READY_INTERVAL); > value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); > } while (((value & SCRATCH_PAD_IOP1_READY) != > SCRATCH_PAD_IOP1_READY) && (--max_wait_count)); > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h > index 701951a0f715..ec48bc276de6 100644 > --- a/drivers/scsi/pm8001/pm80xx_hwi.h > +++ b/drivers/scsi/pm8001/pm80xx_hwi.h > @@ -1639,3 +1639,9 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t; > > #define MEMBASE_II_SHIFT_REGISTER 0x1010 > #endif > + > +/** > + * As we know sleep (1~20) ms may result in sleep longer than ~20 ms, hence we > + * choose 20 ms interval. > + */ > +#define FW_READY_INTERVAL 20 > -- > 2.16.3 >