Thread (36 messages) 36 messages, 6 authors, 2023-12-07

Re: [PATCH v2 01/10] devm-helpers: introduce devm_mutex_init

From: Hans de Goede <hidden>
Date: 2023-12-06 19:55:13
Also in: linux-leds, lkml

Hi,

On 12/6/23 19:58, George Stark wrote:
Hello Hans

Thanks for the review.

On 12/6/23 18:01, Hans de Goede wrote:
quoted
Hi George,

On 12/4/23 19:05, George Stark wrote:
quoted
Using of devm API leads to certain order of releasing resources.
So all dependent resources which are not devm-wrapped should be deleted
with respect to devm-release order. Mutex is one of such objects that
often is bound to other resources and has no own devm wrapping.
Since mutex_destroy() actually does nothing in non-debug builds
frequently calling mutex_destroy() is just ignored which is safe for now
but wrong formally and can lead to a problem if mutex_destroy() is
extended so introduce devm_mutex_init().

Signed-off-by: George Stark <redacted>
---
  include/linux/devm-helpers.h | 18 ++++++++++++++++++
  1 file changed, 18 insertions(+)
diff --git a/include/linux/devm-helpers.h b/include/linux/devm-helpers.h
index 74891802200d..2f56e476776f 100644
--- a/include/linux/devm-helpers.h
+++ b/include/linux/devm-helpers.h
@@ -76,4 +76,22 @@ static inline int devm_work_autocancel(struct device *dev,
      return devm_add_action(dev, devm_work_drop, w);
  }
  +static inline void devm_mutex_release(void *res)
+{
+    mutex_destroy(res);
+}
+
+/**
+ * devm_mutex_init - Resource-managed mutex initialization
+ * @dev:    Device which lifetime work is bound to
+ * @lock:    Pointer to a mutex
+ *
+ * Initialize mutex which is automatically destroyed when driver is detached.
+ */
+static inline int devm_mutex_init(struct device *dev, struct mutex *lock)
+{
+    mutex_init(lock);
+    return devm_add_action_or_reset(dev, devm_mutex_release, lock);
+}
+
  #endif
mutex_destroy() only actually does anything if CONFIG_DEBUG_MUTEXES
is set, otherwise it is an empty inline-stub.

Adding a devres resource to the device just to call an empty inline
stub which is a no-op seems like a waste of resources. IMHO it
would be better to change this to:

static inline int devm_mutex_init(struct device *dev, struct mutex *lock)
{
    mutex_init(lock);
#ifdef CONFIG_DEBUG_MUTEXES
    return devm_add_action_or_reset(dev, devm_mutex_release, lock);
#else
    return 0;
#endif
}

To avoid the unnecessary devres allocation when
CONFIG_DEBUG_MUTEXES is not set.
Honestly saying I don't like unnecessary devres allocation either but the proposed approach has its own price:

1) we'll have more than one place with branching if mutex_destroy is empty or not using  indirect condition. If suddenly mutex_destroy is extended for non-debug code (in upstream branch or e.g. by someone for local debug) than there'll be a problem.

2) If mutex_destroy is empty or not depends on CONFIG_PREEMPT_RT option too. When CONFIG_PREEMPT_RT is on mutex_destroy is always empty.

As I see it only the mutex interface (mutex.h) has to say definitely if mutex_destroy must be called. Probably we could add some define to include/linux/mutex.h,like IS_MUTEX_DESTROY_REQUIRED and declare it near mutex_destroy definition itself.
That (a  IS_MUTEX_DESTROY_REQUIRED define) is an interesting idea. Lets see for v3 if the mutex maintainers will accept that and if not then I guess we will just need to live with the unnecessary devres allocation.

Regards,

Hans

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help