From: Can Guo <cang@codeaurora.org>
To: Stanley Chu <stanley.chu@mediatek.com>
Cc: linux-scsi@vger.kernel.org, martin.petersen@oracle.com,
andy.teng@mediatek.com, jejb@linux.ibm.com,
chun-hung.wu@mediatek.com, kuohong.wang@mediatek.com,
linux-kernel@vger.kernel.org, asutoshd@codeaurora.org,
avri.altman@wdc.com, linux-mediatek@lists.infradead.org,
peter.wang@mediatek.com, alim.akhtar@samsung.com,
matthias.bgg@gmail.com, beanhuo@micron.com,
chaotian.jing@mediatek.com, cc.chou@mediatek.com,
linux-arm-kernel@lists.infradead.org, bvanassche@acm.org
Subject: Re: [PATCH v2] scsi: ufs: Fix possible infinite loop in ufshcd_hold
Date: Wed, 29 Jul 2020 16:43:27 +0800 [thread overview]
Message-ID: <bfbb48b06fa3464da0cbd2aee8a32649@codeaurora.org> (raw)
In-Reply-To: <20200729024037.23105-1-stanley.chu@mediatek.com>
Hi Stanley,
On 2020-07-29 10:40, Stanley Chu wrote:
> In ufshcd_suspend(), after clk-gating is suspended and link is set
> as Hibern8 state, ufshcd_hold() is still possibly invoked before
> ufshcd_suspend() returns. For example, MediaTek's suspend vops may
> issue UIC commands which would call ufshcd_hold() during the command
> issuing flow.
>
> Now if UFSHCD_CAP_HIBERN8_WITH_CLK_GATING capability is enabled,
> then ufshcd_hold() may enter infinite loops because there is no
> clk-ungating work scheduled or pending. In this case, ufshcd_hold()
> shall just bypass, and keep the link as Hibern8 state.
>
The infinite loop is expected as ufshcd_hold is called again after
link is put to hibern8 state, so in QCOM's code, we never do this.
The cap UFSHCD_CAP_HIBERN8_WITH_CLK_GATING means UIC link state
must not be HIBERN8 after ufshcd_hold(async=false) returns.
Instead of bailing out from that loop, which makes the logic of
ufshcd_hold and clk gating even more complex, how about removing
ufshcd_hold/release from ufshcd_send_uic_cmd()? I think they are
redundant and we should never send DME cmds if clocks/powers are
not ready. I mean callers should make sure they are ready to send
DME cmds (and only callers know when), but not leave that job to
ufshcd_send_uic_cmd(). It is convenient to remove ufshcd_hold/
release from ufshcd_send_uic_cmd() as there are not many places
sending DME cmds without holding the clocks, ufs_bsg.c is one.
And I have tested my idea on my setup, it worked well for me.
Another benefit is that it also allows us to use DME cmds
in clk gating/ungating contexts if we need to in the future.
Please let me know your idea, thanks.
Can Guo.
> Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
> Signed-off-by: Andy Teng <andy.teng@mediatek.com>
>
> ---
>
> Changes since v1:
> - Fix return value: Use unique bool variable to get the result of
> flush_work(). Thcan prevent incorrect returned value, i.e., rc, if
> flush_work() returns true
> - Fix commit message
>
> ---
> drivers/scsi/ufs/ufshcd.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index 577cc0d7487f..acba2271c5d3 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -1561,6 +1561,7 @@ static void ufshcd_ungate_work(struct work_struct
> *work)
> int ufshcd_hold(struct ufs_hba *hba, bool async)
> {
> int rc = 0;
> + bool flush_result;
> unsigned long flags;
>
> if (!ufshcd_is_clkgating_allowed(hba))
> @@ -1592,7 +1593,9 @@ int ufshcd_hold(struct ufs_hba *hba, bool async)
> break;
> }
> spin_unlock_irqrestore(hba->host->host_lock, flags);
> - flush_work(&hba->clk_gating.ungate_work);
> + flush_result = flush_work(&hba->clk_gating.ungate_work);
> + if (hba->clk_gating.is_suspended && !flush_result)
> + goto out;
> spin_lock_irqsave(hba->host->host_lock, flags);
> goto start;
> }
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
WARNING: multiple messages have this Message-ID (diff)
From: Can Guo <cang@codeaurora.org>
To: Stanley Chu <stanley.chu@mediatek.com>
Cc: linux-scsi@vger.kernel.org, martin.petersen@oracle.com,
avri.altman@wdc.com, alim.akhtar@samsung.com, jejb@linux.ibm.com,
bvanassche@acm.org, beanhuo@micron.com, asutoshd@codeaurora.org,
matthias.bgg@gmail.com, linux-mediatek@lists.infradead.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, kuohong.wang@mediatek.com,
peter.wang@mediatek.com, chun-hung.wu@mediatek.com,
andy.teng@mediatek.com, chaotian.jing@mediatek.com,
cc.chou@mediatek.com
Subject: Re: [PATCH v2] scsi: ufs: Fix possible infinite loop in ufshcd_hold
Date: Wed, 29 Jul 2020 16:43:27 +0800 [thread overview]
Message-ID: <bfbb48b06fa3464da0cbd2aee8a32649@codeaurora.org> (raw)
In-Reply-To: <20200729024037.23105-1-stanley.chu@mediatek.com>
Hi Stanley,
On 2020-07-29 10:40, Stanley Chu wrote:
> In ufshcd_suspend(), after clk-gating is suspended and link is set
> as Hibern8 state, ufshcd_hold() is still possibly invoked before
> ufshcd_suspend() returns. For example, MediaTek's suspend vops may
> issue UIC commands which would call ufshcd_hold() during the command
> issuing flow.
>
> Now if UFSHCD_CAP_HIBERN8_WITH_CLK_GATING capability is enabled,
> then ufshcd_hold() may enter infinite loops because there is no
> clk-ungating work scheduled or pending. In this case, ufshcd_hold()
> shall just bypass, and keep the link as Hibern8 state.
>
The infinite loop is expected as ufshcd_hold is called again after
link is put to hibern8 state, so in QCOM's code, we never do this.
The cap UFSHCD_CAP_HIBERN8_WITH_CLK_GATING means UIC link state
must not be HIBERN8 after ufshcd_hold(async=false) returns.
Instead of bailing out from that loop, which makes the logic of
ufshcd_hold and clk gating even more complex, how about removing
ufshcd_hold/release from ufshcd_send_uic_cmd()? I think they are
redundant and we should never send DME cmds if clocks/powers are
not ready. I mean callers should make sure they are ready to send
DME cmds (and only callers know when), but not leave that job to
ufshcd_send_uic_cmd(). It is convenient to remove ufshcd_hold/
release from ufshcd_send_uic_cmd() as there are not many places
sending DME cmds without holding the clocks, ufs_bsg.c is one.
And I have tested my idea on my setup, it worked well for me.
Another benefit is that it also allows us to use DME cmds
in clk gating/ungating contexts if we need to in the future.
Please let me know your idea, thanks.
Can Guo.
> Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
> Signed-off-by: Andy Teng <andy.teng@mediatek.com>
>
> ---
>
> Changes since v1:
> - Fix return value: Use unique bool variable to get the result of
> flush_work(). Thcan prevent incorrect returned value, i.e., rc, if
> flush_work() returns true
> - Fix commit message
>
> ---
> drivers/scsi/ufs/ufshcd.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index 577cc0d7487f..acba2271c5d3 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -1561,6 +1561,7 @@ static void ufshcd_ungate_work(struct work_struct
> *work)
> int ufshcd_hold(struct ufs_hba *hba, bool async)
> {
> int rc = 0;
> + bool flush_result;
> unsigned long flags;
>
> if (!ufshcd_is_clkgating_allowed(hba))
> @@ -1592,7 +1593,9 @@ int ufshcd_hold(struct ufs_hba *hba, bool async)
> break;
> }
> spin_unlock_irqrestore(hba->host->host_lock, flags);
> - flush_work(&hba->clk_gating.ungate_work);
> + flush_result = flush_work(&hba->clk_gating.ungate_work);
> + if (hba->clk_gating.is_suspended && !flush_result)
> + goto out;
> spin_lock_irqsave(hba->host->host_lock, flags);
> goto start;
> }
WARNING: multiple messages have this Message-ID (diff)
From: Can Guo <cang@codeaurora.org>
To: Stanley Chu <stanley.chu@mediatek.com>
Cc: linux-scsi@vger.kernel.org, martin.petersen@oracle.com,
andy.teng@mediatek.com, jejb@linux.ibm.com,
chun-hung.wu@mediatek.com, kuohong.wang@mediatek.com,
linux-kernel@vger.kernel.org, asutoshd@codeaurora.org,
avri.altman@wdc.com, linux-mediatek@lists.infradead.org,
peter.wang@mediatek.com, alim.akhtar@samsung.com,
matthias.bgg@gmail.com, beanhuo@micron.com,
chaotian.jing@mediatek.com, cc.chou@mediatek.com,
linux-arm-kernel@lists.infradead.org, bvanassche@acm.org
Subject: Re: [PATCH v2] scsi: ufs: Fix possible infinite loop in ufshcd_hold
Date: Wed, 29 Jul 2020 16:43:27 +0800 [thread overview]
Message-ID: <bfbb48b06fa3464da0cbd2aee8a32649@codeaurora.org> (raw)
In-Reply-To: <20200729024037.23105-1-stanley.chu@mediatek.com>
Hi Stanley,
On 2020-07-29 10:40, Stanley Chu wrote:
> In ufshcd_suspend(), after clk-gating is suspended and link is set
> as Hibern8 state, ufshcd_hold() is still possibly invoked before
> ufshcd_suspend() returns. For example, MediaTek's suspend vops may
> issue UIC commands which would call ufshcd_hold() during the command
> issuing flow.
>
> Now if UFSHCD_CAP_HIBERN8_WITH_CLK_GATING capability is enabled,
> then ufshcd_hold() may enter infinite loops because there is no
> clk-ungating work scheduled or pending. In this case, ufshcd_hold()
> shall just bypass, and keep the link as Hibern8 state.
>
The infinite loop is expected as ufshcd_hold is called again after
link is put to hibern8 state, so in QCOM's code, we never do this.
The cap UFSHCD_CAP_HIBERN8_WITH_CLK_GATING means UIC link state
must not be HIBERN8 after ufshcd_hold(async=false) returns.
Instead of bailing out from that loop, which makes the logic of
ufshcd_hold and clk gating even more complex, how about removing
ufshcd_hold/release from ufshcd_send_uic_cmd()? I think they are
redundant and we should never send DME cmds if clocks/powers are
not ready. I mean callers should make sure they are ready to send
DME cmds (and only callers know when), but not leave that job to
ufshcd_send_uic_cmd(). It is convenient to remove ufshcd_hold/
release from ufshcd_send_uic_cmd() as there are not many places
sending DME cmds without holding the clocks, ufs_bsg.c is one.
And I have tested my idea on my setup, it worked well for me.
Another benefit is that it also allows us to use DME cmds
in clk gating/ungating contexts if we need to in the future.
Please let me know your idea, thanks.
Can Guo.
> Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
> Signed-off-by: Andy Teng <andy.teng@mediatek.com>
>
> ---
>
> Changes since v1:
> - Fix return value: Use unique bool variable to get the result of
> flush_work(). Thcan prevent incorrect returned value, i.e., rc, if
> flush_work() returns true
> - Fix commit message
>
> ---
> drivers/scsi/ufs/ufshcd.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index 577cc0d7487f..acba2271c5d3 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -1561,6 +1561,7 @@ static void ufshcd_ungate_work(struct work_struct
> *work)
> int ufshcd_hold(struct ufs_hba *hba, bool async)
> {
> int rc = 0;
> + bool flush_result;
> unsigned long flags;
>
> if (!ufshcd_is_clkgating_allowed(hba))
> @@ -1592,7 +1593,9 @@ int ufshcd_hold(struct ufs_hba *hba, bool async)
> break;
> }
> spin_unlock_irqrestore(hba->host->host_lock, flags);
> - flush_work(&hba->clk_gating.ungate_work);
> + flush_result = flush_work(&hba->clk_gating.ungate_work);
> + if (hba->clk_gating.is_suspended && !flush_result)
> + goto out;
> spin_lock_irqsave(hba->host->host_lock, flags);
> goto start;
> }
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-07-29 8:43 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-29 2:40 [PATCH v2] scsi: ufs: Fix possible infinite loop in ufshcd_hold Stanley Chu
2020-07-29 2:40 ` Stanley Chu
2020-07-29 2:40 ` Stanley Chu
2020-07-29 8:43 ` Can Guo [this message]
2020-07-29 8:43 ` Can Guo
2020-07-29 8:43 ` Can Guo
2020-07-29 10:26 ` Stanley Chu
2020-07-29 10:26 ` Stanley Chu
2020-07-29 10:26 ` Stanley Chu
2020-07-29 10:53 ` Can Guo
2020-07-29 10:53 ` Can Guo
2020-07-29 10:53 ` Can Guo
2020-07-30 7:59 ` Stanley Chu
2020-07-30 7:59 ` Stanley Chu
2020-07-30 7:59 ` Stanley Chu
2020-08-04 5:27 ` [SPAM]Re: " Stanley Chu
2020-08-04 5:27 ` Stanley Chu
2020-08-04 6:10 ` Avri Altman
2020-08-04 6:10 ` Avri Altman
2020-08-07 0:39 ` Stanley Chu
2020-08-07 0:39 ` Stanley Chu
2020-08-07 0:39 ` Stanley Chu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=bfbb48b06fa3464da0cbd2aee8a32649@codeaurora.org \
--to=cang@codeaurora.org \
--cc=alim.akhtar@samsung.com \
--cc=andy.teng@mediatek.com \
--cc=asutoshd@codeaurora.org \
--cc=avri.altman@wdc.com \
--cc=beanhuo@micron.com \
--cc=bvanassche@acm.org \
--cc=cc.chou@mediatek.com \
--cc=chaotian.jing@mediatek.com \
--cc=chun-hung.wu@mediatek.com \
--cc=jejb@linux.ibm.com \
--cc=kuohong.wang@mediatek.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=matthias.bgg@gmail.com \
--cc=peter.wang@mediatek.com \
--cc=stanley.chu@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.