diff mbox series

[RESEND] i2c: bcm-iproc: Fix bcm_iproc_i2c_isr deadlock issue

Message ID 20230706211414.10660-1-dg573847474@gmail.com (mailing list archive)
State New, archived
Headers show
Series [RESEND] i2c: bcm-iproc: Fix bcm_iproc_i2c_isr deadlock issue | expand

Commit Message

Chengfeng Ye July 6, 2023, 9:14 p.m. UTC
iproc_i2c_rd_reg and iproc_i2c_wr_reg are called from both
interrupt context (e.g. bcm_iproc_i2c_isr) and process context
(e.g. bcm_iproc_i2c_suspend). Therefore, interrupts should be
disabled to avoid potential deadlock. To prevent this scenario,
use spin_lock_irqsave.

Signed-off-by: Chengfeng Ye <dg573847474@gmail.com>
---
 drivers/i2c/busses/i2c-bcm-iproc.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

Comments

Chengfeng Ye July 6, 2023, 9:21 p.m. UTC | #1
Hi Ray and Wolfram,

> I can't apply it, what version is this against?

The patch is based on 6.4-rc7. I resend the patch with this
email because I had some problems setting up the previous
one with git send-email. That patch was manually pasted
so that might be the reason for not being able to be applied.

Best Regards,
Chengfeng
Scott Branden July 6, 2023, 11:02 p.m. UTC | #2
Some comments inline

On 2023-07-06 14:14, Chengfeng Ye wrote:
> iproc_i2c_rd_reg and iproc_i2c_wr_reg are called from both
> interrupt context (e.g. bcm_iproc_i2c_isr) and process context
> (e.g. bcm_iproc_i2c_suspend). Therefore, interrupts should be
> disabled to avoid potential deadlock. To prevent this scenario,
> use spin_lock_irqsave.
> 
Add Fixes: tag here.
> Signed-off-by: Chengfeng Ye <dg573847474@gmail.com>
> ---
>   drivers/i2c/busses/i2c-bcm-iproc.c | 10 ++++++----
>   1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c
> index 85d8a6b04885..d02245e4db8c 100644
> --- a/drivers/i2c/busses/i2c-bcm-iproc.c
> +++ b/drivers/i2c/busses/i2c-bcm-iproc.c
> @@ -233,13 +233,14 @@ static inline u32 iproc_i2c_rd_reg(struct bcm_iproc_i2c_dev *iproc_i2c,
>   				   u32 offset)
>   {
>   	u32 val;
> +	unsigned long flags;
>   
>   	if (iproc_i2c->idm_base) {
> -		spin_lock(&iproc_i2c->idm_lock);
> +		spin_lock_irqsave(&iproc_i2c->idm_lock, flags);
>   		writel(iproc_i2c->ape_addr_mask,
>   		       iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET);
>   		val = readl(iproc_i2c->base + offset);
> -		spin_unlock(&iproc_i2c->idm_lock);
> +		spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags);
>   	} else {
>   		val = readl(iproc_i2c->base + offset);
>   	}
> @@ -250,12 +251,13 @@ static inline u32 iproc_i2c_rd_reg(struct bcm_iproc_i2c_dev *iproc_i2c,
>   static inline void iproc_i2c_wr_reg(struct bcm_iproc_i2c_dev *iproc_i2c,
>   				    u32 offset, u32 val)
>   {
> +	unsigned long flags;
Add newline after variable declarations.
>   	if (iproc_i2c->idm_base) {
> -		spin_lock(&iproc_i2c->idm_lock);
> +		spin_lock_irqsave(&iproc_i2c->idm_lock, flags);
>   		writel(iproc_i2c->ape_addr_mask,
>   		       iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET);
>   		writel(val, iproc_i2c->base + offset);
> -		spin_unlock(&iproc_i2c->idm_lock);
> +		spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags);
>   	} else {
>   		writel(val, iproc_i2c->base + offset);
>   	}
Ray Jui July 6, 2023, 11:19 p.m. UTC | #3
On 7/6/2023 2:21 PM, Chengfeng Ye wrote:
> Hi Ray and Wolfram,
> 
>> I can't apply it, what version is this against?
> 
> The patch is based on 6.4-rc7. I resend the patch with this
> email because I had some problems setting up the previous
> one with git send-email. That patch was manually pasted
> so that might be the reason for not being able to be applied.
> 
> Best Regards,
> Chengfeng

I saw your latest patch. You should use prefix of [PATCH V2]
instead of [PATCH RESEND].

Also, can you please add the fix tag I identified to your commit
message. That will save Wolfram some
manual work.

Thanks,

Ray
Chengfeng Ye July 7, 2023, 8:52 a.m. UTC | #4
> Also, can you please add the fix tag I identified to your commit
> message. That will save Wolfram some
> manual work.

> Add newline after variable declarations.

Thanks for the reply.
Fixed these problems in v2 patch.

Best Regards,
Chengfeng
diff mbox series

Patch

diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c
index 85d8a6b04885..d02245e4db8c 100644
--- a/drivers/i2c/busses/i2c-bcm-iproc.c
+++ b/drivers/i2c/busses/i2c-bcm-iproc.c
@@ -233,13 +233,14 @@  static inline u32 iproc_i2c_rd_reg(struct bcm_iproc_i2c_dev *iproc_i2c,
 				   u32 offset)
 {
 	u32 val;
+	unsigned long flags;
 
 	if (iproc_i2c->idm_base) {
-		spin_lock(&iproc_i2c->idm_lock);
+		spin_lock_irqsave(&iproc_i2c->idm_lock, flags);
 		writel(iproc_i2c->ape_addr_mask,
 		       iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET);
 		val = readl(iproc_i2c->base + offset);
-		spin_unlock(&iproc_i2c->idm_lock);
+		spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags);
 	} else {
 		val = readl(iproc_i2c->base + offset);
 	}
@@ -250,12 +251,13 @@  static inline u32 iproc_i2c_rd_reg(struct bcm_iproc_i2c_dev *iproc_i2c,
 static inline void iproc_i2c_wr_reg(struct bcm_iproc_i2c_dev *iproc_i2c,
 				    u32 offset, u32 val)
 {
+	unsigned long flags;
 	if (iproc_i2c->idm_base) {
-		spin_lock(&iproc_i2c->idm_lock);
+		spin_lock_irqsave(&iproc_i2c->idm_lock, flags);
 		writel(iproc_i2c->ape_addr_mask,
 		       iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET);
 		writel(val, iproc_i2c->base + offset);
-		spin_unlock(&iproc_i2c->idm_lock);
+		spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags);
 	} else {
 		writel(val, iproc_i2c->base + offset);
 	}