Re: [PATCH V2 3/4] pm80xx: Avoid busywait in FW ready check

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

 



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
>



[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