2024-01-22 08:32:18

by SEO HOYOUNG

[permalink] [raw]
Subject: [PATCH v1] scsi: ufs: core: Remove the ufshcd_release in ufshcd_err_handling_prepare

If err_handler is performed in the suspend/resume situation, ufs_release
can be called twice and active_reqs valid can be negative.
This is because ufshcd_errhandling_prepare() and
ufshcd_err_handling_unprepare() repeatedly release calls.
Eventually, active_reqs have a value different from the intention.
To prevent this, release duplication processing was removed.

Signed-off-by: SEO HOYOUNG <[email protected]>
---
drivers/ufs/core/ufshcd.c | 1 -
1 file changed, 1 deletion(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 7c59d7a02243..423e83074a20 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -6351,7 +6351,6 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba)
ufshcd_hold(hba);
if (!ufshcd_is_clkgating_allowed(hba))
ufshcd_setup_clocks(hba, true);
- ufshcd_release(hba);
pm_op = hba->is_sys_suspended ? UFS_SYSTEM_PM : UFS_RUNTIME_PM;
ufshcd_vops_resume(hba, pm_op);
} else {
--
2.26.0



2024-01-22 20:36:46

by Bart Van Assche

[permalink] [raw]
Subject: Re: [PATCH v1] scsi: ufs: core: Remove the ufshcd_release in ufshcd_err_handling_prepare

On 1/22/24 00:33, SEO HOYOUNG wrote:
> If err_handler is performed in the suspend/resume situation, ufs_release
> can be called twice and active_reqs valid can be negative.
> This is because ufshcd_errhandling_prepare() and
> ufshcd_err_handling_unprepare() repeatedly release calls.
> Eventually, active_reqs have a value different from the intention.
> To prevent this, release duplication processing was removed.
>
> Signed-off-by: SEO HOYOUNG <[email protected]>
> ---
> drivers/ufs/core/ufshcd.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
> index 7c59d7a02243..423e83074a20 100644
> --- a/drivers/ufs/core/ufshcd.c
> +++ b/drivers/ufs/core/ufshcd.c
> @@ -6351,7 +6351,6 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba)
> ufshcd_hold(hba);
> if (!ufshcd_is_clkgating_allowed(hba))
> ufshcd_setup_clocks(hba, true);
> - ufshcd_release(hba);
> pm_op = hba->is_sys_suspended ? UFS_SYSTEM_PM : UFS_RUNTIME_PM;
> ufshcd_vops_resume(hba, pm_op);
> } else {

I think that the above ufshcd_release() call pairs with the ufshcd_hold()
call three lines above it and hence that removing that call would be
wrong.

Thanks,

Bart.

2024-01-23 03:11:26

by SEO HOYOUNG

[permalink] [raw]
Subject: RE: [PATCH v1] scsi: ufs: core: Remove the ufshcd_release in ufshcd_err_handling_prepare

> -----Original Message-----
> From: Bart Van Assche <[email protected]>
> Sent: Tuesday, January 23, 2024 5:37 AM
> To: SEO HOYOUNG <[email protected]>; [email protected]; linux-
> [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]
> Subject: Re: [PATCH v1] scsi: ufs: core: Remove the ufshcd_release in
> ufshcd_err_handling_prepare
>
> On 1/22/24 00:33, SEO HOYOUNG wrote:
> > If err_handler is performed in the suspend/resume situation,
> > ufs_release can be called twice and active_reqs valid can be negative.
> > This is because ufshcd_errhandling_prepare() and
> > ufshcd_err_handling_unprepare() repeatedly release calls.
> > Eventually, active_reqs have a value different from the intention.
> > To prevent this, release duplication processing was removed.
> >
> > Signed-off-by: SEO HOYOUNG <[email protected]>
> > ---
> > drivers/ufs/core/ufshcd.c | 1 -
> > 1 file changed, 1 deletion(-)
> >
> > diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
> > index 7c59d7a02243..423e83074a20 100644
> > --- a/drivers/ufs/core/ufshcd.c
> > +++ b/drivers/ufs/core/ufshcd.c
> > @@ -6351,7 +6351,6 @@ static void ufshcd_err_handling_prepare(struct
> ufs_hba *hba)
> > ufshcd_hold(hba);
> > if (!ufshcd_is_clkgating_allowed(hba))
> > ufshcd_setup_clocks(hba, true);
> > - ufshcd_release(hba);
> > pm_op = hba->is_sys_suspended ? UFS_SYSTEM_PM :
> UFS_RUNTIME_PM;
> > ufshcd_vops_resume(hba, pm_op);
> > } else {
>
> I think that the above ufshcd_release() call pairs with the ufshcd_hold()
> call three lines above it and hence that removing that call would be wrong.
>
> Thanks,
>
> Bart.

Hi,

It was a different when I tested it.
If __ufshcd_wl_resume() is called active_reqs is 1.
Because ufshcd_hold() is called in __ufshcd_wl_suspend().
If occurred hibern8_exit failed in __ufschd_wl_resume(), ufshcd_release()
is called in the :out syntax, and active_reqs becomes 0.
After that, active_reqs becomes 0 because ufshcd_hold() is called
from ufshcd_err_handling_repare()and ufshcd_release() is called again while
err_handler is operating.
When err_handler is completed, active_reqs becomes negative because
ufshcd_release() is called again in ufshcd_err_handling_unprepare().
I tested it while printing the log, and if I misanalyzed it, let me know.

Thanks,

SEO.


2024-01-24 16:17:33

by Bart Van Assche

[permalink] [raw]
Subject: Re: [PATCH v1] scsi: ufs: core: Remove the ufshcd_release in ufshcd_err_handling_prepare

On 1/22/24 18:38, hoyoung seo wrote:
> When err_handler is completed, active_reqs becomes negative because
> ufshcd_release() is called again in ufshcd_err_handling_unprepare().
> I tested it while printing the log, and if I misanalyzed it, let me know.

Please repeat your analysis. I think this patch is wrong.

Thanks,

Bart.

2024-01-31 08:23:45

by SEO HOYOUNG

[permalink] [raw]
Subject: RE: [PATCH v1] scsi: ufs: core: Remove the ufshcd_release in ufshcd_err_handling_prepare

> -----Original Message-----
> From: Bart Van Assche <[email protected]>
> Sent: Thursday, January 25, 2024 1:17 AM
> To: hoyoung seo <[email protected]>; [email protected]; linux-
> [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]
> Subject: Re: [PATCH v1] scsi: ufs: core: Remove the ufshcd_release in
> ufshcd_err_handling_prepare
>
> On 1/22/24 18:38, hoyoung seo wrote:
> > When err_handler is completed, active_reqs becomes negative because
> > ufshcd_release() is called again in ufshcd_err_handling_unprepare().
> > I tested it while printing the log, and if I misanalyzed it, let me know.
>
> Please repeat your analysis. I think this patch is wrong.
>
> Thanks,
>
> Bart.

Hi,

I do not understand. why you said my patch is wrong.
If ufs entered suspend with hibern8 state then the hba->clk_gating.active_reqs is 1.
After that run wl_resume(), ufs drvier send hibern8 exit command.
At that time, if the command timeout or error occurs, the err_handler is activated.
Then the active_reqs pair may not fit.

So to sum up, ufs_release() is performed 3 time.
(wl_resume(), ufshcd_err_handling_prepare(), ufshcd_err_handling_unprepare())
And the ufshcd_hold() is performed 2 time(__ufshcd_wl_suspend(), ufshcd_err_handling_prepare())
So the paire of active_reqs is not correct.
So I deleted the ufshcd_release() in ufshcd_err_handling_prepare().

The ufshcd_release() was not called again even in the pm_op_in_progress state in 4.xx version of the kernel.
But now if is_sys_suspended is 1, then ufshcd_release() is called once more.
I don't understand why this is added and the pair doesn't fit.

Please check it again.
Thanks.

Seo.


2024-01-31 17:40:49

by Bart Van Assche

[permalink] [raw]
Subject: Re: [PATCH v1] scsi: ufs: core: Remove the ufshcd_release in ufshcd_err_handling_prepare

On 1/31/24 00:23, hoyoung seo wrote:
> I do not understand. why you said my patch is wrong.

My apologies - I misread the patch.

Bart.


2024-01-31 18:15:26

by Bart Van Assche

[permalink] [raw]
Subject: Re: [PATCH v1] scsi: ufs: core: Remove the ufshcd_release in ufshcd_err_handling_prepare

On 1/22/24 00:33, SEO HOYOUNG wrote:
> This is because ufshcd_errhandling_prepare() and
> ufshcd_err_handling_unprepare() repeatedly release calls.

It would have been much more clear if it would have been mentioned that
ufshcd_err_handling_prepare() should call ufshcd_hold() once and
also that ufshcd_err_handling_unprepare() should call ufshcd_release()
once.

Additionally, a Fixes: tag is missing. Is this patch perhaps a fix for commit
c72e79c0ad2b ("scsi: ufs: Recover HBA runtime PM error in error handler")?
Can Guo, since you wrote that patch, can you please take a look at this patch?

> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
> index 7c59d7a02243..423e83074a20 100644
> --- a/drivers/ufs/core/ufshcd.c
> +++ b/drivers/ufs/core/ufshcd.c
> @@ -6351,7 +6351,6 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba)
> ufshcd_hold(hba);
> if (!ufshcd_is_clkgating_allowed(hba))
> ufshcd_setup_clocks(hba, true);
> - ufshcd_release(hba);
> pm_op = hba->is_sys_suspended ? UFS_SYSTEM_PM : UFS_RUNTIME_PM;
> ufshcd_vops_resume(hba, pm_op);
> } else {

Reviewed-by: Bart Van Assche <[email protected]>

2024-02-01 03:52:02

by Can Guo

[permalink] [raw]
Subject: Re: [PATCH v1] scsi: ufs: core: Remove the ufshcd_release in ufshcd_err_handling_prepare



On 2/1/2024 1:44 AM, Bart Van Assche wrote:
> On 1/22/24 00:33, SEO HOYOUNG wrote:
>> This is because ufshcd_errhandling_prepare() and
>> ufshcd_err_handling_unprepare() repeatedly release calls.
>
> It would have been much more clear if it would have been mentioned that
> ufshcd_err_handling_prepare() should call ufshcd_hold() once and
> also that ufshcd_err_handling_unprepare() should call ufshcd_release()
> once.
>
> Additionally, a Fixes: tag is missing. Is this patch perhaps a fix for
> commit
> c72e79c0ad2b ("scsi: ufs: Recover HBA runtime PM error in error handler")?
> Can Guo, since you wrote that patch, can you please take a look at this
> patch?
>
>> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
>> index 7c59d7a02243..423e83074a20 100644
>> --- a/drivers/ufs/core/ufshcd.c
>> +++ b/drivers/ufs/core/ufshcd.c
>> @@ -6351,7 +6351,6 @@ static void ufshcd_err_handling_prepare(struct
>> ufs_hba *hba)
>>           ufshcd_hold(hba);
>>           if (!ufshcd_is_clkgating_allowed(hba))
>>               ufshcd_setup_clocks(hba, true);
>> -        ufshcd_release(hba);

When we are here, it means runtime resume has failed.

When I wrote the code (in older kernel), ufshcd_runtime_resume(), if
fails, bails without calling ufshcd_release(), eventually
ufshcd_err_handling_unprepare() would call ufshcd_release() to balance.

But now, I see that if __ufshcd_wl_resume() fails, ufshcd_release() is
called anyways, so ufshcd_release() is not required here. Hence,

Reviewed-by: Can Guo <[email protected]>

>>           pm_op = hba->is_sys_suspended ? UFS_SYSTEM_PM : UFS_RUNTIME_PM;
>>           ufshcd_vops_resume(hba, pm_op);
>>       } else {
>
> Reviewed-by: Bart Van Assche <[email protected]>

2024-02-06 02:09:54

by Martin K. Petersen

[permalink] [raw]
Subject: Re: [PATCH v1] scsi: ufs: core: Remove the ufshcd_release in ufshcd_err_handling_prepare

On Mon, 22 Jan 2024 17:33:24 +0900, SEO HOYOUNG wrote:

> If err_handler is performed in the suspend/resume situation, ufs_release
> can be called twice and active_reqs valid can be negative.
> This is because ufshcd_errhandling_prepare() and
> ufshcd_err_handling_unprepare() repeatedly release calls.
> Eventually, active_reqs have a value different from the intention.
> To prevent this, release duplication processing was removed.
>
> [...]

Applied to 6.8/scsi-fixes, thanks!

[1/1] scsi: ufs: core: Remove the ufshcd_release in ufshcd_err_handling_prepare
https://git.kernel.org/mkp/scsi/c/17e94b258541

--
Martin K. Petersen Oracle Linux Engineering