linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] PM / OPP: Call notifier without holding opp_table->lock
       [not found] <59C2414E.6020803@samsung.com>
@ 2017-09-20 15:34 ` Viresh Kumar
  2017-09-20 17:00   ` Stephen Boyd
  2017-09-20 20:25 ` [PATCH V2] " Viresh Kumar
  2017-09-21 17:44 ` [PATCH V3] " Viresh Kumar
  2 siblings, 1 reply; 7+ messages in thread
From: Viresh Kumar @ 2017-09-20 15:34 UTC (permalink / raw)
  To: Rafael Wysocki, cw00.choi, Viresh Kumar, Nishanth Menon, Stephen Boyd
  Cc: Viresh Kumar, linux-pm, Vincent Guittot, myungjoo.ham, inki.dae,
	linux-kernel

The notifier callbacks may want to call some OPP helper routines which
may try to take the same opp_table->lock again and cause a deadlock. One
such usecase was reported by Chanwoo Choi, where calling
dev_pm_opp_disable() leads us to the devfreq's OPP notifier handler,
which further calls dev_pm_opp_find_freq_floor() and it deadlocks.

We don't really need the opp_table->lock to be held across the notifier
call though, all we want to make sure is that the 'opp' doesn't get
freed while being used from within the notifier chain. We can do it with
help of dev_pm_opp_get/put() as well. Lets do it.

Reported-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/base/power/opp/core.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c
index 4360b4efcd4c..668fd940d362 100644
--- a/drivers/base/power/opp/core.c
+++ b/drivers/base/power/opp/core.c
@@ -1627,6 +1627,9 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
 
 	opp->available = availability_req;
 
+	dev_pm_opp_get(opp);
+	mutex_unlock(&opp_table->lock);
+
 	/* Notify the change of the OPP availability */
 	if (availability_req)
 		blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_ENABLE,
@@ -1635,8 +1638,12 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
 		blocking_notifier_call_chain(&opp_table->head,
 					     OPP_EVENT_DISABLE, opp);
 
+	dev_pm_opp_put(opp);
+	goto put_table;
+
 unlock:
 	mutex_unlock(&opp_table->lock);
+put_table:
 	dev_pm_opp_put_opp_table(opp_table);
 	return r;
 }
-- 
2.7.4

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

* Re: [PATCH] PM / OPP: Call notifier without holding opp_table->lock
  2017-09-20 15:34 ` [PATCH] PM / OPP: Call notifier without holding opp_table->lock Viresh Kumar
@ 2017-09-20 17:00   ` Stephen Boyd
  2017-09-20 17:07     ` Viresh Kumar
  0 siblings, 1 reply; 7+ messages in thread
From: Stephen Boyd @ 2017-09-20 17:00 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael Wysocki, cw00.choi, Viresh Kumar, Nishanth Menon,
	linux-pm, Vincent Guittot, myungjoo.ham, inki.dae, linux-kernel

On 09/20, Viresh Kumar wrote:
> The notifier callbacks may want to call some OPP helper routines which
> may try to take the same opp_table->lock again and cause a deadlock. One
> such usecase was reported by Chanwoo Choi, where calling
> dev_pm_opp_disable() leads us to the devfreq's OPP notifier handler,
> which further calls dev_pm_opp_find_freq_floor() and it deadlocks.
> 
> We don't really need the opp_table->lock to be held across the notifier
> call though, all we want to make sure is that the 'opp' doesn't get
> freed while being used from within the notifier chain. We can do it with
> help of dev_pm_opp_get/put() as well. Lets do it.

s/Lets/Let's/

> 
> Reported-by: Chanwoo Choi <cw00.choi@samsung.com>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
>  drivers/base/power/opp/core.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c
> index 4360b4efcd4c..668fd940d362 100644
> --- a/drivers/base/power/opp/core.c
> +++ b/drivers/base/power/opp/core.c
> @@ -1627,6 +1627,9 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
>  
>  	opp->available = availability_req;
>  
> +	dev_pm_opp_get(opp);
> +	mutex_unlock(&opp_table->lock);

Does this prevent the OPP from changing while the lock is
released? That would be the only difference from before. It's
possible that nobody cares about this situation though.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCH] PM / OPP: Call notifier without holding opp_table->lock
  2017-09-20 17:00   ` Stephen Boyd
@ 2017-09-20 17:07     ` Viresh Kumar
  2017-09-20 19:47       ` Stephen Boyd
  0 siblings, 1 reply; 7+ messages in thread
From: Viresh Kumar @ 2017-09-20 17:07 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Rafael Wysocki, cw00.choi, Viresh Kumar, Nishanth Menon,
	linux-pm, Vincent Guittot, myungjoo.ham, inki.dae, linux-kernel

On 20-09-17, 10:00, Stephen Boyd wrote:
> On 09/20, Viresh Kumar wrote:

> > diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c
> > index 4360b4efcd4c..668fd940d362 100644
> > --- a/drivers/base/power/opp/core.c
> > +++ b/drivers/base/power/opp/core.c
> > @@ -1627,6 +1627,9 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
> >  
> >  	opp->available = availability_req;
> >  
> > +	dev_pm_opp_get(opp);
> > +	mutex_unlock(&opp_table->lock);
> 
> Does this prevent the OPP from changing while the lock is
> released?

No, its just ref counting and will only prevent it from getting freed.

There is only one thing that can change for an OPP though after it is
created, its availability.

> That would be the only difference from before. It's
> possible that nobody cares about this situation though.

I am not sure if its worth caring for right now :)

Also the notifier chain will not start again until the previous call
chain is finished. So we are kind of synchronized here.

-- 
viresh

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

* Re: [PATCH] PM / OPP: Call notifier without holding opp_table->lock
  2017-09-20 17:07     ` Viresh Kumar
@ 2017-09-20 19:47       ` Stephen Boyd
  0 siblings, 0 replies; 7+ messages in thread
From: Stephen Boyd @ 2017-09-20 19:47 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael Wysocki, cw00.choi, Viresh Kumar, Nishanth Menon,
	linux-pm, Vincent Guittot, myungjoo.ham, inki.dae, linux-kernel

On 09/20, Viresh Kumar wrote:
> On 20-09-17, 10:00, Stephen Boyd wrote:
> > On 09/20, Viresh Kumar wrote:
> 
> > > diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c
> > > index 4360b4efcd4c..668fd940d362 100644
> > > --- a/drivers/base/power/opp/core.c
> > > +++ b/drivers/base/power/opp/core.c
> > > @@ -1627,6 +1627,9 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
> > >  
> > >  	opp->available = availability_req;
> > >  
> > > +	dev_pm_opp_get(opp);
> > > +	mutex_unlock(&opp_table->lock);
> > 
> > Does this prevent the OPP from changing while the lock is
> > released?
> 
> No, its just ref counting and will only prevent it from getting freed.
> 
> There is only one thing that can change for an OPP though after it is
> created, its availability.

Ok.

> 
> > That would be the only difference from before. It's
> > possible that nobody cares about this situation though.
> 
> I am not sure if its worth caring for right now :)
> 
> Also the notifier chain will not start again until the previous call
> chain is finished. So we are kind of synchronized here.
> 

Yep. Just me worrying out loud. You can add my

Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* [PATCH V2] PM / OPP: Call notifier without holding opp_table->lock
       [not found] <59C2414E.6020803@samsung.com>
  2017-09-20 15:34 ` [PATCH] PM / OPP: Call notifier without holding opp_table->lock Viresh Kumar
@ 2017-09-20 20:25 ` Viresh Kumar
  2017-09-20 23:58   ` Chanwoo Choi
  2017-09-21 17:44 ` [PATCH V3] " Viresh Kumar
  2 siblings, 1 reply; 7+ messages in thread
From: Viresh Kumar @ 2017-09-20 20:25 UTC (permalink / raw)
  To: Rafael Wysocki, cw00.choi, Viresh Kumar, Nishanth Menon, Stephen Boyd
  Cc: Viresh Kumar, linux-pm, Vincent Guittot, myungjoo.ham, inki.dae,
	linux-kernel

The notifier callbacks may want to call some OPP helper routines which
may try to take the same opp_table->lock again and cause a deadlock. One
such usecase was reported by Chanwoo Choi, where calling
dev_pm_opp_disable() leads us to the devfreq's OPP notifier handler,
which further calls dev_pm_opp_find_freq_floor() and it deadlocks.

We don't really need the opp_table->lock to be held across the notifier
call though, all we want to make sure is that the 'opp' doesn't get
freed while being used from within the notifier chain. We can do it with
help of dev_pm_opp_get/put() as well. Let's do it.

Reported-by: Chanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
V1->V2:
- s/Lets/Let's/ in commit log and added Stephen's tag.

 drivers/base/power/opp/core.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c
index 4360b4efcd4c..668fd940d362 100644
--- a/drivers/base/power/opp/core.c
+++ b/drivers/base/power/opp/core.c
@@ -1627,6 +1627,9 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
 
 	opp->available = availability_req;
 
+	dev_pm_opp_get(opp);
+	mutex_unlock(&opp_table->lock);
+
 	/* Notify the change of the OPP availability */
 	if (availability_req)
 		blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_ENABLE,
@@ -1635,8 +1638,12 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
 		blocking_notifier_call_chain(&opp_table->head,
 					     OPP_EVENT_DISABLE, opp);
 
+	dev_pm_opp_put(opp);
+	goto put_table;
+
 unlock:
 	mutex_unlock(&opp_table->lock);
+put_table:
 	dev_pm_opp_put_opp_table(opp_table);
 	return r;
 }
-- 
2.7.4

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

* Re: [PATCH V2] PM / OPP: Call notifier without holding opp_table->lock
  2017-09-20 20:25 ` [PATCH V2] " Viresh Kumar
@ 2017-09-20 23:58   ` Chanwoo Choi
  0 siblings, 0 replies; 7+ messages in thread
From: Chanwoo Choi @ 2017-09-20 23:58 UTC (permalink / raw)
  To: Viresh Kumar, Rafael Wysocki, Viresh Kumar, Nishanth Menon, Stephen Boyd
  Cc: linux-pm, Vincent Guittot, myungjoo.ham, inki.dae, linux-kernel

Hi Viresh,

On 2017년 09월 21일 05:25, Viresh Kumar wrote:
> The notifier callbacks may want to call some OPP helper routines which
> may try to take the same opp_table->lock again and cause a deadlock. One
> such usecase was reported by Chanwoo Choi, where calling
> dev_pm_opp_disable() leads us to the devfreq's OPP notifier handler,
> which further calls dev_pm_opp_find_freq_floor() and it deadlocks.
> 
> We don't really need the opp_table->lock to be held across the notifier
> call though, all we want to make sure is that the 'opp' doesn't get
> freed while being used from within the notifier chain. We can do it with
> help of dev_pm_opp_get/put() as well. Let's do it.
> 
> Reported-by: Chanwoo Choi <cw00.choi@samsung.com>
> Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> V1->V2:
> - s/Lets/Let's/ in commit log and added Stephen's tag.
> 

Thanks for your fixup. Looks good to me.
IMHO, this patch should be posted to stable@vger.kernel.org.

Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>

[snip] 

-- 
Best Regards,
Chanwoo Choi
Samsung Electronics

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

* [PATCH V3] PM / OPP: Call notifier without holding opp_table->lock
       [not found] <59C2414E.6020803@samsung.com>
  2017-09-20 15:34 ` [PATCH] PM / OPP: Call notifier without holding opp_table->lock Viresh Kumar
  2017-09-20 20:25 ` [PATCH V2] " Viresh Kumar
@ 2017-09-21 17:44 ` Viresh Kumar
  2 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2017-09-21 17:44 UTC (permalink / raw)
  To: Rafael Wysocki, cw00.choi, Viresh Kumar, Nishanth Menon, Stephen Boyd
  Cc: Viresh Kumar, linux-pm, Vincent Guittot, myungjoo.ham, inki.dae,
	4 . 11+ # 4 . 11+,
	linux-kernel

The notifier callbacks may want to call some OPP helper routines which
may try to take the same opp_table->lock again and cause a deadlock. One
such usecase was reported by Chanwoo Choi, where calling
dev_pm_opp_disable() leads us to the devfreq's OPP notifier handler,
which further calls dev_pm_opp_find_freq_floor() and it deadlocks.

We don't really need the opp_table->lock to be held across the notifier
call though, all we want to make sure is that the 'opp' doesn't get
freed while being used from within the notifier chain. We can do it with
help of dev_pm_opp_get/put() as well. Let's do it.

Cc: 4.11+ <stable@vger.kernel.org> # 4.11+
Fixes: 5b650b388844 ("PM / OPP: Take kref from _find_opp_table()")
Reported-by: Chanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
V2->V3:
- Added fixes, Cc and tags from Chanwoo.

 drivers/base/power/opp/core.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c
index 4360b4efcd4c..668fd940d362 100644
--- a/drivers/base/power/opp/core.c
+++ b/drivers/base/power/opp/core.c
@@ -1627,6 +1627,9 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
 
 	opp->available = availability_req;
 
+	dev_pm_opp_get(opp);
+	mutex_unlock(&opp_table->lock);
+
 	/* Notify the change of the OPP availability */
 	if (availability_req)
 		blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_ENABLE,
@@ -1635,8 +1638,12 @@ static int _opp_set_availability(struct device *dev, unsigned long freq,
 		blocking_notifier_call_chain(&opp_table->head,
 					     OPP_EVENT_DISABLE, opp);
 
+	dev_pm_opp_put(opp);
+	goto put_table;
+
 unlock:
 	mutex_unlock(&opp_table->lock);
+put_table:
 	dev_pm_opp_put_opp_table(opp_table);
 	return r;
 }
-- 
2.7.4

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

end of thread, other threads:[~2017-09-21 17:44 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <59C2414E.6020803@samsung.com>
2017-09-20 15:34 ` [PATCH] PM / OPP: Call notifier without holding opp_table->lock Viresh Kumar
2017-09-20 17:00   ` Stephen Boyd
2017-09-20 17:07     ` Viresh Kumar
2017-09-20 19:47       ` Stephen Boyd
2017-09-20 20:25 ` [PATCH V2] " Viresh Kumar
2017-09-20 23:58   ` Chanwoo Choi
2017-09-21 17:44 ` [PATCH V3] " Viresh Kumar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).