All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] pinctrl: core: Make p->state in order in pinctrl_commit_state
@ 2022-10-27  6:51 Maria Yu
  2022-10-27  7:24 ` Greg KH
  2022-11-08 12:47 ` Linus Walleij
  0 siblings, 2 replies; 9+ messages in thread
From: Maria Yu @ 2022-10-27  6:51 UTC (permalink / raw)
  To: linus.walleij; +Cc: Maria Yu, linux-gpio, stable

We've got a dump that current cpu is in pinctrl_commit_state, the
old_state != p->state while the stack is still in the process of
pinmux_disable_setting. So it means even if the current p->state is
changed in new state, the settings are not yet up-to-date enabled
complete yet.

Currently p->state in different value to synchronize the
pinctrl_commit_state behaviors. The p->state will have transaction like
old_state -> NULL -> new_state. When in old_state, it will try to
disable all the all state settings. And when after new state settings
enabled, p->state will changed to the new state after that. So use
smp_mb to synchronize the p->state variable and the settings in order.
---
 drivers/pinctrl/core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 9e57f4c62e60..cd917a5b1a0a 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -1256,6 +1256,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
 		}
 	}
 
+	smp_mb();
 	p->state = NULL;
 
 	/* Apply all the settings for the new state - pinmux first */
@@ -1305,6 +1306,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
 			pinctrl_link_add(setting->pctldev, p->dev);
 	}
 
+	smp_mb();
 	p->state = state;
 
 	return 0;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] pinctrl: core: Make p->state in order in pinctrl_commit_state
  2022-10-27  6:51 [PATCH] pinctrl: core: Make p->state in order in pinctrl_commit_state Maria Yu
@ 2022-10-27  7:24 ` Greg KH
  2022-10-27  8:43   ` Aiqun Yu (Maria)
  2022-11-08 12:47 ` Linus Walleij
  1 sibling, 1 reply; 9+ messages in thread
From: Greg KH @ 2022-10-27  7:24 UTC (permalink / raw)
  To: Maria Yu; +Cc: linus.walleij, linux-gpio, stable

On Thu, Oct 27, 2022 at 02:51:10PM +0800, Maria Yu wrote:
> We've got a dump that current cpu is in pinctrl_commit_state, the
> old_state != p->state while the stack is still in the process of
> pinmux_disable_setting. So it means even if the current p->state is
> changed in new state, the settings are not yet up-to-date enabled
> complete yet.
> 
> Currently p->state in different value to synchronize the
> pinctrl_commit_state behaviors. The p->state will have transaction like
> old_state -> NULL -> new_state. When in old_state, it will try to
> disable all the all state settings. And when after new state settings
> enabled, p->state will changed to the new state after that. So use
> smp_mb to synchronize the p->state variable and the settings in order.
> ---
>  drivers/pinctrl/core.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
> index 9e57f4c62e60..cd917a5b1a0a 100644
> --- a/drivers/pinctrl/core.c
> +++ b/drivers/pinctrl/core.c
> @@ -1256,6 +1256,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
>  		}
>  	}
>  
> +	smp_mb();
>  	p->state = NULL;
>  
>  	/* Apply all the settings for the new state - pinmux first */
> @@ -1305,6 +1306,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
>  			pinctrl_link_add(setting->pctldev, p->dev);
>  	}
>  
> +	smp_mb();
>  	p->state = state;
>  
>  	return 0;
> -- 
> 2.17.1
> 

<formletter>

This is not the correct way to submit patches for inclusion in the
stable kernel tree.  Please read:
    https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
for how to do this properly.

</formletter>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH] pinctrl: core: Make p->state in order in pinctrl_commit_state
  2022-10-27  7:24 ` Greg KH
@ 2022-10-27  8:43   ` Aiqun Yu (Maria)
  0 siblings, 0 replies; 9+ messages in thread
From: Aiqun Yu (Maria) @ 2022-10-27  8:43 UTC (permalink / raw)
  To: Greg KH, Aiqun Yu (QUIC); +Cc: linus.walleij, linux-gpio, stable

Thx Greg,

Pls ignore this thread. Already correct to the normal  linux-kernel@vger.kernel.org  in another email thread.

Thx and BRs,
Aiqun Yu (Maria)

-----Original Message-----
From: Greg KH <gregkh@linuxfoundation.org> 
Sent: Thursday, October 27, 2022 3:24 PM
To: Aiqun Yu (QUIC) <quic_aiquny@quicinc.com>
Cc: linus.walleij@linaro.org; linux-gpio@vger.kernel.org; stable@vger.kernel.org
Subject: Re: [PATCH] pinctrl: core: Make p->state in order in pinctrl_commit_state

WARNING: This email originated from outside of Qualcomm. Please be wary of any links or attachments, and do not enable macros.

On Thu, Oct 27, 2022 at 02:51:10PM +0800, Maria Yu wrote:
> We've got a dump that current cpu is in pinctrl_commit_state, the 
> old_state != p->state while the stack is still in the process of 
> pinmux_disable_setting. So it means even if the current p->state is 
> changed in new state, the settings are not yet up-to-date enabled 
> complete yet.
>
> Currently p->state in different value to synchronize the 
> pinctrl_commit_state behaviors. The p->state will have transaction 
> like old_state -> NULL -> new_state. When in old_state, it will try to 
> disable all the all state settings. And when after new state settings 
> enabled, p->state will changed to the new state after that. So use 
> smp_mb to synchronize the p->state variable and the settings in order.
> ---
>  drivers/pinctrl/core.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 
> 9e57f4c62e60..cd917a5b1a0a 100644
> --- a/drivers/pinctrl/core.c
> +++ b/drivers/pinctrl/core.c
> @@ -1256,6 +1256,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
>               }
>       }
>
> +     smp_mb();
>       p->state = NULL;
>
>       /* Apply all the settings for the new state - pinmux first */ @@ 
> -1305,6 +1306,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
>                       pinctrl_link_add(setting->pctldev, p->dev);
>       }
>
> +     smp_mb();
>       p->state = state;
>
>       return 0;
> --
> 2.17.1
>

<formletter>

This is not the correct way to submit patches for inclusion in the stable kernel tree.  Please read:
    https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
for how to do this properly.

</formletter>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] pinctrl: core: Make p->state in order in pinctrl_commit_state
  2022-10-27  6:51 [PATCH] pinctrl: core: Make p->state in order in pinctrl_commit_state Maria Yu
  2022-10-27  7:24 ` Greg KH
@ 2022-11-08 12:47 ` Linus Walleij
  2022-11-08 19:20   ` Paul E. McKenney
  1 sibling, 1 reply; 9+ messages in thread
From: Linus Walleij @ 2022-11-08 12:47 UTC (permalink / raw)
  To: Maria Yu, Paul E. McKenney, Arnd Bergmann; +Cc: linux-gpio, stable

Hi Maria,

thanks for your patch!

On Thu, Oct 27, 2022 at 8:51 AM Maria Yu <quic_aiquny@quicinc.com> wrote:

> We've got a dump that current cpu is in pinctrl_commit_state, the
> old_state != p->state while the stack is still in the process of
> pinmux_disable_setting. So it means even if the current p->state is
> changed in new state, the settings are not yet up-to-date enabled
> complete yet.
>
> Currently p->state in different value to synchronize the
> pinctrl_commit_state behaviors. The p->state will have transaction like
> old_state -> NULL -> new_state. When in old_state, it will try to
> disable all the all state settings. And when after new state settings
> enabled, p->state will changed to the new state after that. So use
> smp_mb to synchronize the p->state variable and the settings in order.
> ---
>  drivers/pinctrl/core.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
> index 9e57f4c62e60..cd917a5b1a0a 100644
> --- a/drivers/pinctrl/core.c
> +++ b/drivers/pinctrl/core.c
> @@ -1256,6 +1256,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
>                 }
>         }
>
> +       smp_mb();
>         p->state = NULL;
>
>         /* Apply all the settings for the new state - pinmux first */
> @@ -1305,6 +1306,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
>                         pinctrl_link_add(setting->pctldev, p->dev);
>         }
>
> +       smp_mb();
>         p->state = state;
>
>         return 0;

Ow!

It's not often that I loop in Paul McKenney on patches, but this is in the core
of the subsystem used across all architectures so if this is a generic problem
of concurrency, I really want some professional concurrency person to
look at it before I apply it.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] pinctrl: core: Make p->state in order in pinctrl_commit_state
  2022-11-08 12:47 ` Linus Walleij
@ 2022-11-08 19:20   ` Paul E. McKenney
  2022-11-09 10:01     ` Aiqun(Maria) Yu
  0 siblings, 1 reply; 9+ messages in thread
From: Paul E. McKenney @ 2022-11-08 19:20 UTC (permalink / raw)
  To: Linus Walleij; +Cc: Maria Yu, Arnd Bergmann, linux-gpio, stable

On Tue, Nov 08, 2022 at 01:47:15PM +0100, Linus Walleij wrote:
> Hi Maria,
> 
> thanks for your patch!
> 
> On Thu, Oct 27, 2022 at 8:51 AM Maria Yu <quic_aiquny@quicinc.com> wrote:
> 
> > We've got a dump that current cpu is in pinctrl_commit_state, the
> > old_state != p->state while the stack is still in the process of
> > pinmux_disable_setting. So it means even if the current p->state is
> > changed in new state, the settings are not yet up-to-date enabled
> > complete yet.
> >
> > Currently p->state in different value to synchronize the
> > pinctrl_commit_state behaviors. The p->state will have transaction like
> > old_state -> NULL -> new_state. When in old_state, it will try to
> > disable all the all state settings. And when after new state settings
> > enabled, p->state will changed to the new state after that. So use
> > smp_mb to synchronize the p->state variable and the settings in order.
> > ---
> >  drivers/pinctrl/core.c | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
> > index 9e57f4c62e60..cd917a5b1a0a 100644
> > --- a/drivers/pinctrl/core.c
> > +++ b/drivers/pinctrl/core.c
> > @@ -1256,6 +1256,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
> >                 }
> >         }
> >
> > +       smp_mb();
> >         p->state = NULL;
> >
> >         /* Apply all the settings for the new state - pinmux first */
> > @@ -1305,6 +1306,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
> >                         pinctrl_link_add(setting->pctldev, p->dev);
> >         }
> >
> > +       smp_mb();
> >         p->state = state;
> >
> >         return 0;
> 
> Ow!
> 
> It's not often that I loop in Paul McKenney on patches, but this is in the core
> of the subsystem used across all architectures so if this is a generic problem
> of concurrency, I really want some professional concurrency person to
> look at it before I apply it.

Hello, Linus and Maria!

Insertion of unadorned and uncommented memory barriers does rouse more
than a bit of suspicion, to be sure.  ;-)

Could you please outline what ordering this smp_mb() is intended to
provide?  Yes, my guess is that the p->state change is to be seen as
happening after the prior memory accesses, but:

1.	What is the other side of the interaction doing?  My guess is
	that something is reading p->state and the referencing the same
	memory referenced prior to the pair of smp_mb() calls above.
	For example, are the other relevant memory references referenced
	by the pointer "p"?

	For example, what happens if two of the above updates happen in
	quick succession during the execution of a single instance of
	the other side of the interaction?

2.	Why smp_mb() rather than using smp_store_release() to update
	p->state?

3.	More generally, why unmarked accesses to p->state?  Are the
	other relevant accesses also unmarked?

	Please see these LWN articles for more on the potential dangers
	of unmarked accesses to shared variables:

	Who's afraid of a big bad optimizing compiler?
		https://lwn.net/Articles/793253/

	Calibrating your fear of big bad optimizing compilers
		https://lwn.net/Articles/799218/

4.	There are some tools that can help with this sort of ordering
	code, for example:

	Concurrency bugs should fear the big bad data-race detector (part 1)
		https://lwn.net/Articles/816850/
	Concurrency bugs should fear the big bad data-race detector (part 2)
		https://lwn.net/Articles/816854/

	For this tool (KCSAN) to find a problem, your testing must come
	close to making it happen.

	A design-level full-state-space tool may be found in
	tools/memotry-model.  This tool, as you might expect, is
	restricted to very short code fragments, but does fully handle
	concurrency.  It might take some work to squeeze what you have
	into the confines of this tool.

Again, to evaluate this change, I need to understand what it is trying
to accomplish.

							Thanx, Paul

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] pinctrl: core: Make p->state in order in pinctrl_commit_state
  2022-11-08 19:20   ` Paul E. McKenney
@ 2022-11-09 10:01     ` Aiqun(Maria) Yu
  0 siblings, 0 replies; 9+ messages in thread
From: Aiqun(Maria) Yu @ 2022-11-09 10:01 UTC (permalink / raw)
  To: paulmck, Linus Walleij; +Cc: Arnd Bergmann, linux-gpio, stable

On 11/9/2022 3:20 AM, Paul E. McKenney wrote:
> On Tue, Nov 08, 2022 at 01:47:15PM +0100, Linus Walleij wrote:
>> Hi Maria,
>>
>> thanks for your patch!
>>
>> On Thu, Oct 27, 2022 at 8:51 AM Maria Yu <quic_aiquny@quicinc.com> wrote:
>>
>>> We've got a dump that current cpu is in pinctrl_commit_state, the
>>> old_state != p->state while the stack is still in the process of
>>> pinmux_disable_setting. So it means even if the current p->state is
>>> changed in new state, the settings are not yet up-to-date enabled
>>> complete yet.
>>>
>>> Currently p->state in different value to synchronize the
>>> pinctrl_commit_state behaviors. The p->state will have transaction like
>>> old_state -> NULL -> new_state. When in old_state, it will try to
>>> disable all the all state settings. And when after new state settings
>>> enabled, p->state will changed to the new state after that. So use
>>> smp_mb to synchronize the p->state variable and the settings in order.
>>> ---
>>>   drivers/pinctrl/core.c | 2 ++
>>>   1 file changed, 2 insertions(+)
>>>
>>> diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
>>> index 9e57f4c62e60..cd917a5b1a0a 100644
>>> --- a/drivers/pinctrl/core.c
>>> +++ b/drivers/pinctrl/core.c
>>> @@ -1256,6 +1256,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
>>>                  }
>>>          }
>>>
>>> +       smp_mb();
>>>          p->state = NULL;
>>>
>>>          /* Apply all the settings for the new state - pinmux first */
>>> @@ -1305,6 +1306,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
>>>                          pinctrl_link_add(setting->pctldev, p->dev);
>>>          }
>>>
>>> +       smp_mb();
>>>          p->state = state;
>>>
>>>          return 0;
>>
>> Ow!
>>
>> It's not often that I loop in Paul McKenney on patches, but this is in the core
>> of the subsystem used across all architectures so if this is a generic problem
>> of concurrency, I really want some professional concurrency person to
>> look at it before I apply it.
> 
> Hello, Linus and Maria!
> 
> Insertion of unadorned and uncommented memory barriers does rouse more
> than a bit of suspicion, to be sure.  ;-)
> 
Thx Paul and Linus,

welcome for the discussion and thx for the envolvement, that's what 
values a lot through the open source work.

> Could you please outline what ordering this smp_mb() is intended to
> provide?  Yes, my guess is that the p->state change is to be seen as
> happening after the prior memory accesses, but:
> 
> 1.	What is the other side of the interaction doing?  My guess is
> 	that something is reading p->state and the referencing the same
> 	memory referenced prior to the pair of smp_mb() calls above.
> 	For example, are the other relevant memory references referenced
> 	by the pointer "p"?
> 
> 	For example, what happens if two of the above updates happen in
> 	quick succession during the execution of a single instance of
> 	the other side of the interaction?
> 

we've got a dump that the taskA is in call stack of pinctrl_commit_state 
-> pinmux_disable_setting ->dev_warn , while the old_state is not 
consistant with current p->state.

And from current ramdump, the kernel have warn each ~4us of the same 
dev_warn of "xxx-pinctrl xxx.pinctrl: not freeing pin xxx(GPIO_xxx) as 
part of deactivating group gpioxxx - it is already used for some other 
setting". It last for ~20ms and then have a final sysrq triggered crash.

so here is the possible the senario like below:
|TaskA pinctrl_commit_state| TaskB pinctrl_commit_state
| old_state = p->state;    |
|if (p->state)             | if(p->state); //old_state
|                          |list_for_each_entry
|                          |   pinmux_disable_setting(
|                          |      old_state->settings);
|                          |p->state = NULL;
|                          |list_for_each_entry
|                          | pinmux_enable_setting(
|                          |   new_state->settings);
|                          |p->state = new_state; //new state
|list_for_each_entry       |
|pinmux_disable_setting(   |
|  old_state->settings);   |
| dev_warn("not freeing pin")|
|                          |



> 2.	Why smp_mb() rather than using smp_store_release() to update
> 	p->state?
> 
For now I am a little afraid of the current memroy barrier is still not 
enough and need to use a lock to avoid concurency.

> 3.	More generally, why unmarked accesses to p->state?  Are the
> 	other relevant accesses also unmarked?
> 
> 	Please see these LWN articles for more on the potential dangers
> 	of unmarked accesses to shared variables:
> 
> 	Who's afraid of a big bad optimizing compiler?
> 		https://lwn.net/Articles/793253/
> 
> 	Calibrating your fear of big bad optimizing compilers
> 		https://lwn.net/Articles/799218/
> 
Let me have a study and try.
> 4.	There are some tools that can help with this sort of ordering
> 	code, for example:
> 
> 	Concurrency bugs should fear the big bad data-race detector (part 1)
> 		https://lwn.net/Articles/816850/
> 	Concurrency bugs should fear the big bad data-race detector (part 2)
> 		https://lwn.net/Articles/816854/
> 
> 	For this tool (KCSAN) to find a problem, your testing must come
> 	close to making it happen.
> 
> 	A design-level full-state-space tool may be found in
> 	tools/memotry-model.  This tool, as you might expect, is
> 	restricted to very short code fragments, but does fully handle
> 	concurrency.  It might take some work to squeeze what you have
> 	into the confines of this tool.
> 
Let me have a study and try.
> Again, to evaluate this change, I need to understand what it is trying
> to accomplish.
> 
Sure.
> 							Thanx, Paul
> 


-- 
Thx and BRs,
Aiqun(Maria) Yu

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] pinctrl: core: Make p->state in order in pinctrl_commit_state
  2022-11-01  4:30 ` Pavan Kondeti
@ 2022-11-02  1:26   ` Aiqun(Maria) Yu
  0 siblings, 0 replies; 9+ messages in thread
From: Aiqun(Maria) Yu @ 2022-11-02  1:26 UTC (permalink / raw)
  To: Pavan Kondeti; +Cc: linus.walleij, linux-gpio, linux-kernel

Hi Pavan,

On 11/1/2022 12:30 PM, Pavan Kondeti wrote:
> Hi Maria,
> 
> On Thu, Oct 27, 2022 at 02:54:08PM +0800, Maria Yu wrote:
>> We've got a dump that current cpu is in pinctrl_commit_state, the
>> old_state != p->state while the stack is still in the process of
>> pinmux_disable_setting. So it means even if the current p->state is
>> changed in new state, the settings are not yet up-to-date enabled
>> complete yet.
>>
>> Currently p->state in different value to synchronize the
>> pinctrl_commit_state behaviors. The p->state will have transaction like
>> old_state -> NULL -> new_state. When in old_state, it will try to
>> disable all the all state settings. And when after new state settings
>> enabled, p->state will changed to the new state after that. So use
>> smp_mb to synchronize the p->state variable and the settings in order.
>> ---
>>   drivers/pinctrl/core.c | 2 ++
>>   1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
>> index 9e57f4c62e60..cd917a5b1a0a 100644
>> --- a/drivers/pinctrl/core.c
>> +++ b/drivers/pinctrl/core.c
>> @@ -1256,6 +1256,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
>>   		}
>>   	}
>>   
>> +	smp_mb();
>>   	p->state = NULL;
>>   
>>   	/* Apply all the settings for the new state - pinmux first */
>> @@ -1305,6 +1306,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
>>   			pinctrl_link_add(setting->pctldev, p->dev);
>>   	}
>>   
>> +	smp_mb();
>>   	p->state = state;
>>   
> 
>  From your commit description, are you inferring that this p->state assignment
> re-ordered wrt pinmux_disable_setting()? btw, I don't see any locking that
> protects concurrent access to p->state modifications. For whatever reasons, if
> a client makes concurrent calls to pinctrl_select_state(), we can land up in
> the situation, you are seeing. correct?
correct.
> 
> Thanks,
> Pavan
> 


-- 
Thx and BRs,
Aiqun(Maria) Yu

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] pinctrl: core: Make p->state in order in pinctrl_commit_state
  2022-10-27  6:54 Maria Yu
@ 2022-11-01  4:30 ` Pavan Kondeti
  2022-11-02  1:26   ` Aiqun(Maria) Yu
  0 siblings, 1 reply; 9+ messages in thread
From: Pavan Kondeti @ 2022-11-01  4:30 UTC (permalink / raw)
  To: Maria Yu; +Cc: linus.walleij, linux-gpio, linux-kernel

Hi Maria,

On Thu, Oct 27, 2022 at 02:54:08PM +0800, Maria Yu wrote:
> We've got a dump that current cpu is in pinctrl_commit_state, the
> old_state != p->state while the stack is still in the process of
> pinmux_disable_setting. So it means even if the current p->state is
> changed in new state, the settings are not yet up-to-date enabled
> complete yet.
> 
> Currently p->state in different value to synchronize the
> pinctrl_commit_state behaviors. The p->state will have transaction like
> old_state -> NULL -> new_state. When in old_state, it will try to
> disable all the all state settings. And when after new state settings
> enabled, p->state will changed to the new state after that. So use
> smp_mb to synchronize the p->state variable and the settings in order.
> ---
>  drivers/pinctrl/core.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
> index 9e57f4c62e60..cd917a5b1a0a 100644
> --- a/drivers/pinctrl/core.c
> +++ b/drivers/pinctrl/core.c
> @@ -1256,6 +1256,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
>  		}
>  	}
>  
> +	smp_mb();
>  	p->state = NULL;
>  
>  	/* Apply all the settings for the new state - pinmux first */
> @@ -1305,6 +1306,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
>  			pinctrl_link_add(setting->pctldev, p->dev);
>  	}
>  
> +	smp_mb();
>  	p->state = state;
>  

From your commit description, are you inferring that this p->state assignment
re-ordered wrt pinmux_disable_setting()? btw, I don't see any locking that
protects concurrent access to p->state modifications. For whatever reasons, if
a client makes concurrent calls to pinctrl_select_state(), we can land up in
the situation, you are seeing. correct?

Thanks,
Pavan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH] pinctrl: core: Make p->state in order in pinctrl_commit_state
@ 2022-10-27  6:54 Maria Yu
  2022-11-01  4:30 ` Pavan Kondeti
  0 siblings, 1 reply; 9+ messages in thread
From: Maria Yu @ 2022-10-27  6:54 UTC (permalink / raw)
  To: linus.walleij; +Cc: Maria Yu, linux-gpio, linux-kernel

We've got a dump that current cpu is in pinctrl_commit_state, the
old_state != p->state while the stack is still in the process of
pinmux_disable_setting. So it means even if the current p->state is
changed in new state, the settings are not yet up-to-date enabled
complete yet.

Currently p->state in different value to synchronize the
pinctrl_commit_state behaviors. The p->state will have transaction like
old_state -> NULL -> new_state. When in old_state, it will try to
disable all the all state settings. And when after new state settings
enabled, p->state will changed to the new state after that. So use
smp_mb to synchronize the p->state variable and the settings in order.
---
 drivers/pinctrl/core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 9e57f4c62e60..cd917a5b1a0a 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -1256,6 +1256,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
 		}
 	}
 
+	smp_mb();
 	p->state = NULL;
 
 	/* Apply all the settings for the new state - pinmux first */
@@ -1305,6 +1306,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
 			pinctrl_link_add(setting->pctldev, p->dev);
 	}
 
+	smp_mb();
 	p->state = state;
 
 	return 0;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-11-09 10:02 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-27  6:51 [PATCH] pinctrl: core: Make p->state in order in pinctrl_commit_state Maria Yu
2022-10-27  7:24 ` Greg KH
2022-10-27  8:43   ` Aiqun Yu (Maria)
2022-11-08 12:47 ` Linus Walleij
2022-11-08 19:20   ` Paul E. McKenney
2022-11-09 10:01     ` Aiqun(Maria) Yu
2022-10-27  6:54 Maria Yu
2022-11-01  4:30 ` Pavan Kondeti
2022-11-02  1:26   ` Aiqun(Maria) Yu

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.