linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] regulator: simplify locking
@ 2020-08-09 21:16 Michał Mirosław
  2020-08-09 21:40 ` Dmitry Osipenko
  0 siblings, 1 reply; 9+ messages in thread
From: Michał Mirosław @ 2020-08-09 21:16 UTC (permalink / raw)
  To: Dmitry Osipenko, Liam Girdwood, Mark Brown; +Cc: linux-kernel

Simplify regulator locking by removing locking around locking. rdev->ref
is now accessed only when the lock is taken. The code still smells fishy,
but now its obvious why.

Fixes: f8702f9e4aa7 ("regulator: core: Use ww_mutex for regulators locking")
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/regulator/core.c         | 37 ++++++--------------------------
 include/linux/regulator/driver.h |  1 -
 2 files changed, 6 insertions(+), 32 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 9e18997777d3..b0662927487c 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -45,7 +45,6 @@
 	pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
 
 static DEFINE_WW_CLASS(regulator_ww_class);
-static DEFINE_MUTEX(regulator_nesting_mutex);
 static DEFINE_MUTEX(regulator_list_mutex);
 static LIST_HEAD(regulator_map_list);
 static LIST_HEAD(regulator_ena_gpio_list);
@@ -150,32 +149,13 @@ static bool regulator_ops_is_valid(struct regulator_dev *rdev, int ops)
 static inline int regulator_lock_nested(struct regulator_dev *rdev,
 					struct ww_acquire_ctx *ww_ctx)
 {
-	bool lock = false;
 	int ret = 0;
 
-	mutex_lock(&regulator_nesting_mutex);
+	if (ww_ctx || !mutex_trylock_recursive(&rdev->mutex.base))
+		ret = ww_mutex_lock(&rdev->mutex, ww_ctx);
 
-	if (ww_ctx || !ww_mutex_trylock(&rdev->mutex)) {
-		if (rdev->mutex_owner == current)
-			rdev->ref_cnt++;
-		else
-			lock = true;
-
-		if (lock) {
-			mutex_unlock(&regulator_nesting_mutex);
-			ret = ww_mutex_lock(&rdev->mutex, ww_ctx);
-			mutex_lock(&regulator_nesting_mutex);
-		}
-	} else {
-		lock = true;
-	}
-
-	if (lock && ret != -EDEADLK) {
+	if (ret != -EDEADLK)
 		rdev->ref_cnt++;
-		rdev->mutex_owner = current;
-	}
-
-	mutex_unlock(&regulator_nesting_mutex);
 
 	return ret;
 }
@@ -205,16 +185,11 @@ EXPORT_SYMBOL_GPL(regulator_lock);
  */
 void regulator_unlock(struct regulator_dev *rdev)
 {
-	mutex_lock(&regulator_nesting_mutex);
+	if (WARN_ON_ONCE(rdev->ref_cnt <= 0))
+		return;
 
-	if (--rdev->ref_cnt == 0) {
-		rdev->mutex_owner = NULL;
+	if (--rdev->ref_cnt == 0)
 		ww_mutex_unlock(&rdev->mutex);
-	}
-
-	WARN_ON_ONCE(rdev->ref_cnt < 0);
-
-	mutex_unlock(&regulator_nesting_mutex);
 }
 EXPORT_SYMBOL_GPL(regulator_unlock);
 
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 8539f34ae42b..2fe5b1bcbe2f 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -448,7 +448,6 @@ struct regulator_dev {
 
 	struct blocking_notifier_head notifier;
 	struct ww_mutex mutex; /* consumer lock */
-	struct task_struct *mutex_owner;
 	int ref_cnt;
 	struct module *owner;
 	struct device dev;
-- 
2.20.1


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

* Re: [PATCH] regulator: simplify locking
  2020-08-09 21:16 [PATCH] regulator: simplify locking Michał Mirosław
@ 2020-08-09 21:40 ` Dmitry Osipenko
  2020-08-09 22:30   ` Michał Mirosław
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Osipenko @ 2020-08-09 21:40 UTC (permalink / raw)
  To: Michał Mirosław, Liam Girdwood, Mark Brown; +Cc: linux-kernel

10.08.2020 00:16, Michał Mirosław пишет:
> Simplify regulator locking by removing locking around locking. rdev->ref
> is now accessed only when the lock is taken. The code still smells fishy,
> but now its obvious why.
> 
> Fixes: f8702f9e4aa7 ("regulator: core: Use ww_mutex for regulators locking")
> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> ---
>  drivers/regulator/core.c         | 37 ++++++--------------------------
>  include/linux/regulator/driver.h |  1 -
>  2 files changed, 6 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
> index 9e18997777d3..b0662927487c 100644
> --- a/drivers/regulator/core.c
> +++ b/drivers/regulator/core.c
> @@ -45,7 +45,6 @@
>  	pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
>  
>  static DEFINE_WW_CLASS(regulator_ww_class);
> -static DEFINE_MUTEX(regulator_nesting_mutex);
>  static DEFINE_MUTEX(regulator_list_mutex);
>  static LIST_HEAD(regulator_map_list);
>  static LIST_HEAD(regulator_ena_gpio_list);
> @@ -150,32 +149,13 @@ static bool regulator_ops_is_valid(struct regulator_dev *rdev, int ops)
>  static inline int regulator_lock_nested(struct regulator_dev *rdev,
>  					struct ww_acquire_ctx *ww_ctx)
>  {
> -	bool lock = false;
>  	int ret = 0;
>  
> -	mutex_lock(&regulator_nesting_mutex);
> +	if (ww_ctx || !mutex_trylock_recursive(&rdev->mutex.base))

Have you seen comment to the mutex_trylock_recursive()?

https://elixir.bootlin.com/linux/v5.8/source/include/linux/mutex.h#L205

 * This function should not be used, _ever_. It is purely for hysterical GEM
 * raisins, and once those are gone this will be removed.

I knew about this function and I don't think it's okay to use it, hence
this is why there is that "nesting_mutex" and "owner" checking.

If you disagree, then perhaps you should make another patch to remove
the stale comment to trylock_recursive().

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

* Re: [PATCH] regulator: simplify locking
  2020-08-09 21:40 ` Dmitry Osipenko
@ 2020-08-09 22:30   ` Michał Mirosław
  2020-08-10  0:21     ` Dmitry Osipenko
  2020-08-10 16:23     ` Mark Brown
  0 siblings, 2 replies; 9+ messages in thread
From: Michał Mirosław @ 2020-08-09 22:30 UTC (permalink / raw)
  To: Dmitry Osipenko; +Cc: Liam Girdwood, Mark Brown, linux-kernel

On Mon, Aug 10, 2020 at 12:40:04AM +0300, Dmitry Osipenko wrote:
> 10.08.2020 00:16, Michał Mirosław пишет:
> > Simplify regulator locking by removing locking around locking. rdev->ref
> > is now accessed only when the lock is taken. The code still smells fishy,
> > but now its obvious why.
> > 
> > Fixes: f8702f9e4aa7 ("regulator: core: Use ww_mutex for regulators locking")
> > Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> > ---
> >  drivers/regulator/core.c         | 37 ++++++--------------------------
> >  include/linux/regulator/driver.h |  1 -
> >  2 files changed, 6 insertions(+), 32 deletions(-)
> > 
> > diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
> > index 9e18997777d3..b0662927487c 100644
> > --- a/drivers/regulator/core.c
> > +++ b/drivers/regulator/core.c
> > @@ -45,7 +45,6 @@
> >  	pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
> >  
> >  static DEFINE_WW_CLASS(regulator_ww_class);
> > -static DEFINE_MUTEX(regulator_nesting_mutex);
> >  static DEFINE_MUTEX(regulator_list_mutex);
> >  static LIST_HEAD(regulator_map_list);
> >  static LIST_HEAD(regulator_ena_gpio_list);
> > @@ -150,32 +149,13 @@ static bool regulator_ops_is_valid(struct regulator_dev *rdev, int ops)
> >  static inline int regulator_lock_nested(struct regulator_dev *rdev,
> >  					struct ww_acquire_ctx *ww_ctx)
> >  {
> > -	bool lock = false;
> >  	int ret = 0;
> >  
> > -	mutex_lock(&regulator_nesting_mutex);
> > +	if (ww_ctx || !mutex_trylock_recursive(&rdev->mutex.base))
> 
> Have you seen comment to the mutex_trylock_recursive()?
> 
> https://elixir.bootlin.com/linux/v5.8/source/include/linux/mutex.h#L205
> 
>  * This function should not be used, _ever_. It is purely for hysterical GEM
>  * raisins, and once those are gone this will be removed.
> 
> I knew about this function and I don't think it's okay to use it, hence
> this is why there is that "nesting_mutex" and "owner" checking.
> 
> If you disagree, then perhaps you should make another patch to remove
> the stale comment to trylock_recursive().

I think that reimplementing the function just to not use it is not the
right solution. The whole locking protocol is problematic and this patch
just uncovers one side of it.

Best Regards,
Michał Mirosław

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

* Re: [PATCH] regulator: simplify locking
  2020-08-09 22:30   ` Michał Mirosław
@ 2020-08-10  0:21     ` Dmitry Osipenko
  2020-08-10  0:59       ` Michał Mirosław
  2020-08-10  1:08       ` Michał Mirosław
  2020-08-10 16:23     ` Mark Brown
  1 sibling, 2 replies; 9+ messages in thread
From: Dmitry Osipenko @ 2020-08-10  0:21 UTC (permalink / raw)
  To: Michał Mirosław; +Cc: Liam Girdwood, Mark Brown, linux-kernel

10.08.2020 01:30, Michał Mirosław пишет:
> On Mon, Aug 10, 2020 at 12:40:04AM +0300, Dmitry Osipenko wrote:
>> 10.08.2020 00:16, Michał Mirosław пишет:
>>> Simplify regulator locking by removing locking around locking. rdev->ref
>>> is now accessed only when the lock is taken. The code still smells fishy,
>>> but now its obvious why.
>>>
>>> Fixes: f8702f9e4aa7 ("regulator: core: Use ww_mutex for regulators locking")
>>> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
>>> ---
>>>  drivers/regulator/core.c         | 37 ++++++--------------------------
>>>  include/linux/regulator/driver.h |  1 -
>>>  2 files changed, 6 insertions(+), 32 deletions(-)
>>>
>>> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
>>> index 9e18997777d3..b0662927487c 100644
>>> --- a/drivers/regulator/core.c
>>> +++ b/drivers/regulator/core.c
>>> @@ -45,7 +45,6 @@
>>>  	pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
>>>  
>>>  static DEFINE_WW_CLASS(regulator_ww_class);
>>> -static DEFINE_MUTEX(regulator_nesting_mutex);
>>>  static DEFINE_MUTEX(regulator_list_mutex);
>>>  static LIST_HEAD(regulator_map_list);
>>>  static LIST_HEAD(regulator_ena_gpio_list);
>>> @@ -150,32 +149,13 @@ static bool regulator_ops_is_valid(struct regulator_dev *rdev, int ops)
>>>  static inline int regulator_lock_nested(struct regulator_dev *rdev,
>>>  					struct ww_acquire_ctx *ww_ctx)
>>>  {
>>> -	bool lock = false;
>>>  	int ret = 0;
>>>  
>>> -	mutex_lock(&regulator_nesting_mutex);
>>> +	if (ww_ctx || !mutex_trylock_recursive(&rdev->mutex.base))
>>
>> Have you seen comment to the mutex_trylock_recursive()?
>>
>> https://elixir.bootlin.com/linux/v5.8/source/include/linux/mutex.h#L205
>>
>>  * This function should not be used, _ever_. It is purely for hysterical GEM
>>  * raisins, and once those are gone this will be removed.
>>
>> I knew about this function and I don't think it's okay to use it, hence
>> this is why there is that "nesting_mutex" and "owner" checking.
>>
>> If you disagree, then perhaps you should make another patch to remove
>> the stale comment to trylock_recursive().
> 
> I think that reimplementing the function just to not use it is not the
> right solution. The whole locking protocol is problematic and this patch
> just uncovers one side of it.

It's not clear to me what is uncovered, the ref_cnt was always accessed
under lock. Could you please explain in a more details?

Would be awesome if you could improve the code, but then you should
un-deprecate the trylock_recursive() before making use of it. Maybe
nobody will mind and it all will be good in the end.

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

* Re: [PATCH] regulator: simplify locking
  2020-08-10  0:21     ` Dmitry Osipenko
@ 2020-08-10  0:59       ` Michał Mirosław
  2020-08-10  5:14         ` Dmitry Osipenko
  2020-08-10  1:08       ` Michał Mirosław
  1 sibling, 1 reply; 9+ messages in thread
From: Michał Mirosław @ 2020-08-10  0:59 UTC (permalink / raw)
  To: Dmitry Osipenko; +Cc: Liam Girdwood, Mark Brown, linux-kernel

On Mon, Aug 10, 2020 at 03:21:47AM +0300, Dmitry Osipenko wrote:
> 10.08.2020 01:30, Michał Mirosław пишет:
> > On Mon, Aug 10, 2020 at 12:40:04AM +0300, Dmitry Osipenko wrote:
> >> 10.08.2020 00:16, Michał Mirosław пишет:
> >>> Simplify regulator locking by removing locking around locking. rdev->ref
> >>> is now accessed only when the lock is taken. The code still smells fishy,
> >>> but now its obvious why.
> >>>
> >>> Fixes: f8702f9e4aa7 ("regulator: core: Use ww_mutex for regulators locking")
> >>> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> >>> ---
> >>>  drivers/regulator/core.c         | 37 ++++++--------------------------
> >>>  include/linux/regulator/driver.h |  1 -
> >>>  2 files changed, 6 insertions(+), 32 deletions(-)
> >>>
> >>> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
> >>> index 9e18997777d3..b0662927487c 100644
> >>> --- a/drivers/regulator/core.c
> >>> +++ b/drivers/regulator/core.c
> >>> @@ -45,7 +45,6 @@
> >>>  	pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
> >>>  
> >>>  static DEFINE_WW_CLASS(regulator_ww_class);
> >>> -static DEFINE_MUTEX(regulator_nesting_mutex);
> >>>  static DEFINE_MUTEX(regulator_list_mutex);
> >>>  static LIST_HEAD(regulator_map_list);
> >>>  static LIST_HEAD(regulator_ena_gpio_list);
> >>> @@ -150,32 +149,13 @@ static bool regulator_ops_is_valid(struct regulator_dev *rdev, int ops)
> >>>  static inline int regulator_lock_nested(struct regulator_dev *rdev,
> >>>  					struct ww_acquire_ctx *ww_ctx)
> >>>  {
> >>> -	bool lock = false;
> >>>  	int ret = 0;
> >>>  
> >>> -	mutex_lock(&regulator_nesting_mutex);
> >>> +	if (ww_ctx || !mutex_trylock_recursive(&rdev->mutex.base))
> >>
> >> Have you seen comment to the mutex_trylock_recursive()?
> >>
> >> https://elixir.bootlin.com/linux/v5.8/source/include/linux/mutex.h#L205
> >>
> >>  * This function should not be used, _ever_. It is purely for hysterical GEM
> >>  * raisins, and once those are gone this will be removed.
> >>
> >> I knew about this function and I don't think it's okay to use it, hence
> >> this is why there is that "nesting_mutex" and "owner" checking.
> >>
> >> If you disagree, then perhaps you should make another patch to remove
> >> the stale comment to trylock_recursive().
> > 
> > I think that reimplementing the function just to not use it is not the
> > right solution. The whole locking protocol is problematic and this patch
> > just uncovers one side of it.
> 
> It's not clear to me what is uncovered, the ref_cnt was always accessed
> under lock. Could you please explain in a more details?
> 
> Would be awesome if you could improve the code, but then you should
> un-deprecate the trylock_recursive() before making use of it. Maybe
> nobody will mind and it all will be good in the end.

I'm not sure why the framework wants recursive locking? If only for the
coupling case, then ww_mutex seems the right direction to replace it:
while walking the graph it will detect entering the same node
a second time. But this works only during the locking transaction (with
ww_context != NULL). Allowing recursive regulator_lock() outside of it
seems inviting trouble.

Best Regards,
Michał Mirosław

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

* Re: [PATCH] regulator: simplify locking
  2020-08-10  0:21     ` Dmitry Osipenko
  2020-08-10  0:59       ` Michał Mirosław
@ 2020-08-10  1:08       ` Michał Mirosław
  1 sibling, 0 replies; 9+ messages in thread
From: Michał Mirosław @ 2020-08-10  1:08 UTC (permalink / raw)
  To: Dmitry Osipenko; +Cc: Liam Girdwood, Mark Brown, linux-kernel

On Mon, Aug 10, 2020 at 03:21:47AM +0300, Dmitry Osipenko wrote:
> 10.08.2020 01:30, Michał Mirosław пишет:
> > On Mon, Aug 10, 2020 at 12:40:04AM +0300, Dmitry Osipenko wrote:
> >> 10.08.2020 00:16, Michał Mirosław пишет:
> >>> Simplify regulator locking by removing locking around locking. rdev->ref
> >>> is now accessed only when the lock is taken. The code still smells fishy,
> >>> but now its obvious why.
> >>>
> >>> Fixes: f8702f9e4aa7 ("regulator: core: Use ww_mutex for regulators locking")
> >>> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> >>> ---
> >>>  drivers/regulator/core.c         | 37 ++++++--------------------------
> >>>  include/linux/regulator/driver.h |  1 -
> >>>  2 files changed, 6 insertions(+), 32 deletions(-)
> >>>
> >>> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
> >>> index 9e18997777d3..b0662927487c 100644
> >>> --- a/drivers/regulator/core.c
> >>> +++ b/drivers/regulator/core.c
> >>> @@ -45,7 +45,6 @@
> >>>  	pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
> >>>  
> >>>  static DEFINE_WW_CLASS(regulator_ww_class);
> >>> -static DEFINE_MUTEX(regulator_nesting_mutex);
> >>>  static DEFINE_MUTEX(regulator_list_mutex);
> >>>  static LIST_HEAD(regulator_map_list);
> >>>  static LIST_HEAD(regulator_ena_gpio_list);
> >>> @@ -150,32 +149,13 @@ static bool regulator_ops_is_valid(struct regulator_dev *rdev, int ops)
> >>>  static inline int regulator_lock_nested(struct regulator_dev *rdev,
> >>>  					struct ww_acquire_ctx *ww_ctx)
> >>>  {
> >>> -	bool lock = false;
> >>>  	int ret = 0;
> >>>  
> >>> -	mutex_lock(&regulator_nesting_mutex);
> >>> +	if (ww_ctx || !mutex_trylock_recursive(&rdev->mutex.base))
> >>
> >> Have you seen comment to the mutex_trylock_recursive()?
> >>
> >> https://elixir.bootlin.com/linux/v5.8/source/include/linux/mutex.h#L205
> >>
> >>  * This function should not be used, _ever_. It is purely for hysterical GEM
> >>  * raisins, and once those are gone this will be removed.
> >>
> >> I knew about this function and I don't think it's okay to use it, hence
> >> this is why there is that "nesting_mutex" and "owner" checking.
> >>
> >> If you disagree, then perhaps you should make another patch to remove
> >> the stale comment to trylock_recursive().
> > 
> > I think that reimplementing the function just to not use it is not the
> > right solution. The whole locking protocol is problematic and this patch
> > just uncovers one side of it.
> 
> It's not clear to me what is uncovered, the ref_cnt was always accessed
> under lock. Could you please explain in a more details?
> 
> Would be awesome if you could improve the code, but then you should
> un-deprecate the trylock_recursive() before making use of it. Maybe
> nobody will mind and it all will be good in the end.

This might be a religious argument. Having said that: I believe using
a deprecated function is better than open coding it. Otherwise it would
be forbidden (ie. removed), not just deprecated.

Of course this assumes that you *really* need a recursive mutex here.

Best Regards,
Michał Mirosław

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

* Re: [PATCH] regulator: simplify locking
  2020-08-10  0:59       ` Michał Mirosław
@ 2020-08-10  5:14         ` Dmitry Osipenko
  2020-08-10 16:12           ` Michał Mirosław
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Osipenko @ 2020-08-10  5:14 UTC (permalink / raw)
  To: Michał Mirosław; +Cc: Liam Girdwood, Mark Brown, linux-kernel

10.08.2020 03:59, Michał Mirosław пишет:
> On Mon, Aug 10, 2020 at 03:21:47AM +0300, Dmitry Osipenko wrote:
>> 10.08.2020 01:30, Michał Mirosław пишет:
>>> On Mon, Aug 10, 2020 at 12:40:04AM +0300, Dmitry Osipenko wrote:
>>>> 10.08.2020 00:16, Michał Mirosław пишет:
>>>>> Simplify regulator locking by removing locking around locking. rdev->ref
>>>>> is now accessed only when the lock is taken. The code still smells fishy,
>>>>> but now its obvious why.
>>>>>
>>>>> Fixes: f8702f9e4aa7 ("regulator: core: Use ww_mutex for regulators locking")
>>>>> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
>>>>> ---
>>>>>  drivers/regulator/core.c         | 37 ++++++--------------------------
>>>>>  include/linux/regulator/driver.h |  1 -
>>>>>  2 files changed, 6 insertions(+), 32 deletions(-)
>>>>>
>>>>> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
>>>>> index 9e18997777d3..b0662927487c 100644
>>>>> --- a/drivers/regulator/core.c
>>>>> +++ b/drivers/regulator/core.c
>>>>> @@ -45,7 +45,6 @@
>>>>>  	pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
>>>>>  
>>>>>  static DEFINE_WW_CLASS(regulator_ww_class);
>>>>> -static DEFINE_MUTEX(regulator_nesting_mutex);
>>>>>  static DEFINE_MUTEX(regulator_list_mutex);
>>>>>  static LIST_HEAD(regulator_map_list);
>>>>>  static LIST_HEAD(regulator_ena_gpio_list);
>>>>> @@ -150,32 +149,13 @@ static bool regulator_ops_is_valid(struct regulator_dev *rdev, int ops)
>>>>>  static inline int regulator_lock_nested(struct regulator_dev *rdev,
>>>>>  					struct ww_acquire_ctx *ww_ctx)
>>>>>  {
>>>>> -	bool lock = false;
>>>>>  	int ret = 0;
>>>>>  
>>>>> -	mutex_lock(&regulator_nesting_mutex);
>>>>> +	if (ww_ctx || !mutex_trylock_recursive(&rdev->mutex.base))
>>>>
>>>> Have you seen comment to the mutex_trylock_recursive()?
>>>>
>>>> https://elixir.bootlin.com/linux/v5.8/source/include/linux/mutex.h#L205
>>>>
>>>>  * This function should not be used, _ever_. It is purely for hysterical GEM
>>>>  * raisins, and once those are gone this will be removed.
>>>>
>>>> I knew about this function and I don't think it's okay to use it, hence
>>>> this is why there is that "nesting_mutex" and "owner" checking.
>>>>
>>>> If you disagree, then perhaps you should make another patch to remove
>>>> the stale comment to trylock_recursive().
>>>
>>> I think that reimplementing the function just to not use it is not the
>>> right solution. The whole locking protocol is problematic and this patch
>>> just uncovers one side of it.
>>
>> It's not clear to me what is uncovered, the ref_cnt was always accessed
>> under lock. Could you please explain in a more details?
>>
>> Would be awesome if you could improve the code, but then you should
>> un-deprecate the trylock_recursive() before making use of it. Maybe
>> nobody will mind and it all will be good in the end.
> 
> I'm not sure why the framework wants recursive locking? If only for the
> coupling case, then ww_mutex seems the right direction to replace it:
> while walking the graph it will detect entering the same node
> a second time. But this works only during the locking transaction (with
> ww_context != NULL). Allowing recursive regulator_lock() outside of it
> seems inviting trouble.

Yes, it's for the coupling case. Coupled regulators may have common
ancestors and then the whole sub-tree needs to be locked while operating
with a coupled regulator.

The nested locking usage is discouraged in general because it is a
source of bugs. I guess it should be possible to get rid of all nested
lockings in the regulator core and use a pure ww_mutex, but somebody
should dedicate time to work on it.

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

* Re: [PATCH] regulator: simplify locking
  2020-08-10  5:14         ` Dmitry Osipenko
@ 2020-08-10 16:12           ` Michał Mirosław
  0 siblings, 0 replies; 9+ messages in thread
From: Michał Mirosław @ 2020-08-10 16:12 UTC (permalink / raw)
  To: Dmitry Osipenko; +Cc: Liam Girdwood, Mark Brown, linux-kernel

On Mon, Aug 10, 2020 at 08:14:20AM +0300, Dmitry Osipenko wrote:
> 10.08.2020 03:59, Michał Mirosław пишет:
> > On Mon, Aug 10, 2020 at 03:21:47AM +0300, Dmitry Osipenko wrote:
> >> 10.08.2020 01:30, Michał Mirosław пишет:
> >>> On Mon, Aug 10, 2020 at 12:40:04AM +0300, Dmitry Osipenko wrote:
> >>>> 10.08.2020 00:16, Michał Mirosław пишет:
[...]
> >>>>> -	mutex_lock(&regulator_nesting_mutex);
> >>>>> +	if (ww_ctx || !mutex_trylock_recursive(&rdev->mutex.base))
[...]
> >>> I think that reimplementing the function just to not use it is not the
> >>> right solution. The whole locking protocol is problematic and this patch
> >>> just uncovers one side of it.
> >>
> >> It's not clear to me what is uncovered, the ref_cnt was always accessed
> >> under lock. Could you please explain in a more details?
[...]
> The nested locking usage is discouraged in general because it is a
> source of bugs. I guess it should be possible to get rid of all nested
> lockings in the regulator core and use a pure ww_mutex, but somebody
> should dedicate time to work on it.

So using a deprecated function for deprecated functionality sounds just
appropriate, doesn't it? :-)

Best Regards,
Michał Mirosław

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

* Re: [PATCH] regulator: simplify locking
  2020-08-09 22:30   ` Michał Mirosław
  2020-08-10  0:21     ` Dmitry Osipenko
@ 2020-08-10 16:23     ` Mark Brown
  1 sibling, 0 replies; 9+ messages in thread
From: Mark Brown @ 2020-08-10 16:23 UTC (permalink / raw)
  To: Michał Mirosław; +Cc: Dmitry Osipenko, Liam Girdwood, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1223 bytes --]

On Mon, Aug 10, 2020 at 12:30:30AM +0200, Michał Mirosław wrote:
> On Mon, Aug 10, 2020 at 12:40:04AM +0300, Dmitry Osipenko wrote:
> > 10.08.2020 00:16, Michał Mirosław пишет:

> > > -	mutex_lock(&regulator_nesting_mutex);
> > > +	if (ww_ctx || !mutex_trylock_recursive(&rdev->mutex.base))

> > Have you seen comment to the mutex_trylock_recursive()?

> > https://elixir.bootlin.com/linux/v5.8/source/include/linux/mutex.h#L205

> >  * This function should not be used, _ever_. It is purely for hysterical GEM
> >  * raisins, and once those are gone this will be removed.

> I think that reimplementing the function just to not use it is not the
> right solution. The whole locking protocol is problematic and this patch
> just uncovers one side of it.

OTOH if this is just making the issue more obvious rather than fixing it
then it's much harder to justify adding a new usage of a function people
are trying to remove.  The coupled regulator stuff is definitely a mess
as far as locking is concerned, it really interferes with the model we
had handling regulators separately as much as possible since we're no
longer just walking back up the tree.  ww does seem like the way
forwards.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

end of thread, other threads:[~2020-08-10 16:23 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-09 21:16 [PATCH] regulator: simplify locking Michał Mirosław
2020-08-09 21:40 ` Dmitry Osipenko
2020-08-09 22:30   ` Michał Mirosław
2020-08-10  0:21     ` Dmitry Osipenko
2020-08-10  0:59       ` Michał Mirosław
2020-08-10  5:14         ` Dmitry Osipenko
2020-08-10 16:12           ` Michał Mirosław
2020-08-10  1:08       ` Michał Mirosław
2020-08-10 16:23     ` Mark Brown

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).