diff mbox series

[v7,5/8] scsi: ufs: Fix ufshcd_hold() caused scheduling while atomic

Message ID 1580978008-9327-6-git-send-email-cang@codeaurora.org (mailing list archive)
State Superseded
Headers show
Series UFS driver general fixes bundle 4 | expand

Commit Message

Can Guo Feb. 6, 2020, 8:33 a.m. UTC
The async version of ufshcd_hold(async == true), which is only called
in queuecommand path as for now, is expected to work in atomic context,
thus it should not sleep or schedule out. When it runs into the condition
that clocks are ON but link is still in hibern8 state, it should bail out
without flushing the clock ungate work.

Signed-off-by: Can Guo <cang@codeaurora.org>
Reviewed-by: Hongwu Su <hongwus@codeaurora.org>
Reviewed-by: Asutosh Das <asutoshd@codeaurora.org>
Reviewed-by: Bean Huo <beanhuo@micron.com>
Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/scsi/ufs/ufshcd.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Avri Altman Feb. 6, 2020, 10:28 a.m. UTC | #1
Hi,

> 
> The async version of ufshcd_hold(async == true), which is only called
> in queuecommand path as for now, is expected to work in atomic context,
> thus it should not sleep or schedule out. When it runs into the condition
> that clocks are ON but link is still in hibern8 state, it should bail out
> without flushing the clock ungate work.

Fixes: f2a785ac2312 (scsi: ufshcd: Fix race between clk scaling and ungate work)
> 
> Signed-off-by: Can Guo <cang@codeaurora.org>
> Reviewed-by: Hongwu Su <hongwus@codeaurora.org>
> Reviewed-by: Asutosh Das <asutoshd@codeaurora.org>
> Reviewed-by: Bean Huo <beanhuo@micron.com>
> Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
> ---
>  drivers/scsi/ufs/ufshcd.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index bbc2607..e8f7f9d 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -1518,6 +1518,11 @@ int ufshcd_hold(struct ufs_hba *hba, bool async)
>                  */
>                 if (ufshcd_can_hibern8_during_gating(hba) &&
>                     ufshcd_is_link_hibern8(hba)) {
> +                       if (async) {
> +                               rc = -EAGAIN;
> +                               hba->clk_gating.active_reqs--;
> +                               break;
> +                       }
>                         spin_unlock_irqrestore(hba->host->host_lock, flags);
>                         flush_work(&hba->clk_gating.ungate_work);
>                         spin_lock_irqsave(hba->host->host_lock, flags);
Since now the above code is shared in all cases,
Maybe find a more economical way to pack it?

Thanks,
Avri


> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora
> Forum,
> a Linux Foundation Collaborative Project
Can Guo Feb. 10, 2020, 1:28 a.m. UTC | #2
On 2020-02-06 18:28, Avri Altman wrote:
> Hi,
> 
>> 
>> The async version of ufshcd_hold(async == true), which is only called
>> in queuecommand path as for now, is expected to work in atomic 
>> context,
>> thus it should not sleep or schedule out. When it runs into the 
>> condition
>> that clocks are ON but link is still in hibern8 state, it should bail 
>> out
>> without flushing the clock ungate work.
> 
> Fixes: f2a785ac2312 (scsi: ufshcd: Fix race between clk scaling and 
> ungate work)

Sorry, missed this one, if another version is needed, I will add this 
line.

>> 
>> Signed-off-by: Can Guo <cang@codeaurora.org>
>> Reviewed-by: Hongwu Su <hongwus@codeaurora.org>
>> Reviewed-by: Asutosh Das <asutoshd@codeaurora.org>
>> Reviewed-by: Bean Huo <beanhuo@micron.com>
>> Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
>> ---
>>  drivers/scsi/ufs/ufshcd.c | 5 +++++
>>  1 file changed, 5 insertions(+)
>> 
>> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
>> index bbc2607..e8f7f9d 100644
>> --- a/drivers/scsi/ufs/ufshcd.c
>> +++ b/drivers/scsi/ufs/ufshcd.c
>> @@ -1518,6 +1518,11 @@ int ufshcd_hold(struct ufs_hba *hba, bool 
>> async)
>>                  */
>>                 if (ufshcd_can_hibern8_during_gating(hba) &&
>>                     ufshcd_is_link_hibern8(hba)) {
>> +                       if (async) {
>> +                               rc = -EAGAIN;
>> +                               hba->clk_gating.active_reqs--;
>> +                               break;
>> +                       }
>>                         spin_unlock_irqrestore(hba->host->host_lock, 
>> flags);
>>                         flush_work(&hba->clk_gating.ungate_work);
>>                         spin_lock_irqsave(hba->host->host_lock, 
>> flags);
> Since now the above code is shared in all cases,
> Maybe find a more economical way to pack it?
> 
> Thanks,
> Avri
> 
> 

There are only 2 of this same code pieces in ufshcd_hold() and located
in different cases, meanwhile there can be fall through, I don't see
a good way to pack it, can you suggest if you have any ideas?

Regards,
Can Guo.

>> --
>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora
>> Forum,
>> a Linux Foundation Collaborative Project
Can Guo Feb. 10, 2020, 1:59 a.m. UTC | #3
On 2020-02-10 09:28, Can Guo wrote:
> On 2020-02-06 18:28, Avri Altman wrote:
>> Hi,
>> 
>>> 
>>> The async version of ufshcd_hold(async == true), which is only called
>>> in queuecommand path as for now, is expected to work in atomic 
>>> context,
>>> thus it should not sleep or schedule out. When it runs into the 
>>> condition
>>> that clocks are ON but link is still in hibern8 state, it should bail 
>>> out
>>> without flushing the clock ungate work.
>> 
>> Fixes: f2a785ac2312 (scsi: ufshcd: Fix race between clk scaling and 
>> ungate work)
> 
> Sorry, missed this one, if another version is needed, I will add this 
> line.
> 
>>> 
>>> Signed-off-by: Can Guo <cang@codeaurora.org>
>>> Reviewed-by: Hongwu Su <hongwus@codeaurora.org>
>>> Reviewed-by: Asutosh Das <asutoshd@codeaurora.org>
>>> Reviewed-by: Bean Huo <beanhuo@micron.com>
>>> Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
>>> ---
>>>  drivers/scsi/ufs/ufshcd.c | 5 +++++
>>>  1 file changed, 5 insertions(+)
>>> 
>>> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
>>> index bbc2607..e8f7f9d 100644
>>> --- a/drivers/scsi/ufs/ufshcd.c
>>> +++ b/drivers/scsi/ufs/ufshcd.c
>>> @@ -1518,6 +1518,11 @@ int ufshcd_hold(struct ufs_hba *hba, bool 
>>> async)
>>>                  */
>>>                 if (ufshcd_can_hibern8_during_gating(hba) &&
>>>                     ufshcd_is_link_hibern8(hba)) {
>>> +                       if (async) {
>>> +                               rc = -EAGAIN;
>>> +                               hba->clk_gating.active_reqs--;
>>> +                               break;
>>> +                       }
>>>                         spin_unlock_irqrestore(hba->host->host_lock, 
>>> flags);
>>>                         flush_work(&hba->clk_gating.ungate_work);
>>>                         spin_lock_irqsave(hba->host->host_lock, 
>>> flags);
>> Since now the above code is shared in all cases,
>> Maybe find a more economical way to pack it?
>> 
>> Thanks,
>> Avri
>> 
>> 
> 
> There are only 2 of this same code pieces in ufshcd_hold() and located
> in different cases, meanwhile there can be fall through, I don't see
> a good way to pack it, can you suggest if you have any ideas?
> 

Now, with this patch, there are 2 same code snippets located in CLKS_ON
and REQ_CLKS_ON. If we somehow pack them, say bring in a inline func to
pack them, we would have to tear it down later if we have to fix
something for only one specific case by adding lines into the snippet.
And actually this is the truth, we do have some fixes for CLKS_ON's case
but not yet uploaded, so let's leave it as it is for now.

> Regards,
> Can Guo.
> 
>>> --
>>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora
>>> Forum,
>>> a Linux Foundation Collaborative Project
Avri Altman Feb. 10, 2020, 8:23 a.m. UTC | #4
> >> Fixes: f2a785ac2312 (scsi: ufshcd: Fix race between clk scaling and
> >> ungate work)
> >
> > Sorry, missed this one, if another version is needed, I will add this
> > line.
fair enough.

> >
> >>>
> >>> Signed-off-by: Can Guo <cang@codeaurora.org>
> >>> Reviewed-by: Hongwu Su <hongwus@codeaurora.org>
> >>> Reviewed-by: Asutosh Das <asutoshd@codeaurora.org>
> >>> Reviewed-by: Bean Huo <beanhuo@micron.com>
> >>> Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
> >>> ---
> >>>  drivers/scsi/ufs/ufshcd.c | 5 +++++
> >>>  1 file changed, 5 insertions(+)
> >>>
> >>> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> >>> index bbc2607..e8f7f9d 100644
> >>> --- a/drivers/scsi/ufs/ufshcd.c
> >>> +++ b/drivers/scsi/ufs/ufshcd.c
> >>> @@ -1518,6 +1518,11 @@ int ufshcd_hold(struct ufs_hba *hba, bool
> >>> async)
> >>>                  */
> >>>                 if (ufshcd_can_hibern8_during_gating(hba) &&
> >>>                     ufshcd_is_link_hibern8(hba)) {
> >>> +                       if (async) {
> >>> +                               rc = -EAGAIN;
> >>> +                               hba->clk_gating.active_reqs--;
> >>> +                               break;
> >>> +                       }
> >>>                         spin_unlock_irqrestore(hba->host->host_lock,
> >>> flags);
> >>>                         flush_work(&hba->clk_gating.ungate_work);
> >>>                         spin_lock_irqsave(hba->host->host_lock,
> >>> flags);
> >> Since now the above code is shared in all cases,
> >> Maybe find a more economical way to pack it?
> >>
> >> Thanks,
> >> Avri
> >>
> >>
> >
> > There are only 2 of this same code pieces in ufshcd_hold() and located
> > in different cases, meanwhile there can be fall through, I don't see
> > a good way to pack it, can you suggest if you have any ideas?
> >
> 
> Now, with this patch, there are 2 same code snippets located in CLKS_ON
> and REQ_CLKS_ON. If we somehow pack them, say bring in a inline func to
> pack them, we would have to tear it down later if we have to fix
> something for only one specific case by adding lines into the snippet.
> And actually this is the truth, we do have some fixes for CLKS_ON's case
> but not yet uploaded, so let's leave it as it is for now.
OK.

Thanks,
Avri
diff mbox series

Patch

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index bbc2607..e8f7f9d 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1518,6 +1518,11 @@  int ufshcd_hold(struct ufs_hba *hba, bool async)
 		 */
 		if (ufshcd_can_hibern8_during_gating(hba) &&
 		    ufshcd_is_link_hibern8(hba)) {
+			if (async) {
+				rc = -EAGAIN;
+				hba->clk_gating.active_reqs--;
+				break;
+			}
 			spin_unlock_irqrestore(hba->host->host_lock, flags);
 			flush_work(&hba->clk_gating.ungate_work);
 			spin_lock_irqsave(hba->host->host_lock, flags);