Message ID | 20231214173614.2820929-3-gnstark@salutedevices.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:3b04:b0:fb:cd0c:d3e with SMTP id c4csp8719165dys; Thu, 14 Dec 2023 09:36:54 -0800 (PST) X-Google-Smtp-Source: AGHT+IFo96E3LbjN/KE4o0jxaJLH/9o97HzTr7r6ZcTh1GVM30m95/8F18UI8TlGYs2RBHpR+mvU X-Received: by 2002:a05:6a00:178e:b0:6cb:4361:773c with SMTP id s14-20020a056a00178e00b006cb4361773cmr12309032pfg.5.1702575414212; Thu, 14 Dec 2023 09:36:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702575414; cv=none; d=google.com; s=arc-20160816; b=wpiEy17UUebpIK7PUzm1pobTRxiimnbjyvSdTNL3PgCSDhhuB9vb14P7msuj8YnF+1 b2SeFjZs9mBTdgTLTgPGXNAejTj8vj1EH7b7AXVndQY+86l4EH8TwkUadDeHUg2aG42R CUFyoX53mdzkHJEpeLlms+RrrXEg7z4KJTnN/erVKtDYLyyMCNPlRH5fRzLbfODswNaP cVGMtJycrr6sG4EOxH1x9Kj4j/nf1QdYnN6PAQuPr7KVt6QtzMHEkls+jVCgz+Q7V4Dp daDnaCOOVn28b4cVCuV23qMrClK5iTboy/gIbVVxG7QSmp2fliiPnCa+8XxSTopnlLtP g1hw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:dkim-filter; bh=iVWYFD6b0apij0HQWfsa8gAqaTMVMRAzNodGO05e/bE=; fh=VGV6ajQ72e9w8REvYqgUr7SYaKNgFpS3GtVmljO5VrE=; b=ODk9Bul2wx04jl75DOMKOcfqXAorRtJjmFLKweGd1dJK/TZHNsNcLYYKzTVcheA+Ts e5gRgw/sKSEeeJhYwrwnWecrey/J50MLFA/7FTfaUyRSnz6X/mJrLaDcjhY1BSRurpX5 y+immOFogL601z/NyjKGFP0NN2XoQVxYtWhqrHiaM3TxpccdQtWQe6nLVX3uyhHeWLtO 4b6PBrUhjSQdEMBCf4zYWFJwb7X6xAvN2np983sdECnxMfc48TtA38QgkxK81sKxQwFI 8PEiQ3r+FjNMQDisMM9+R5XNbYkoV4zxLviZYLK+YqzZCURUAq8FyBt+sOwtL4R6SLgr Jyiw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@salutedevices.com header.s=mail header.b=lsJ1+DAj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:5 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=salutedevices.com Received: from groat.vger.email (groat.vger.email. [2620:137:e000::3:5]) by mx.google.com with ESMTPS id fc6-20020a056a002e0600b006cdf20980fasi11702487pfb.80.2023.12.14.09.36.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Dec 2023 09:36:54 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:5 as permitted sender) client-ip=2620:137:e000::3:5; Authentication-Results: mx.google.com; dkim=pass header.i=@salutedevices.com header.s=mail header.b=lsJ1+DAj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:5 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=salutedevices.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by groat.vger.email (Postfix) with ESMTP id E5F81826A049; Thu, 14 Dec 2023 09:36:49 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at groat.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1444082AbjLNRg0 (ORCPT <rfc822;dexuan.linux@gmail.com> + 99 others); Thu, 14 Dec 2023 12:36:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51432 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229864AbjLNRgV (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 14 Dec 2023 12:36:21 -0500 Received: from mx1.sberdevices.ru (mx2.sberdevices.ru [45.89.224.132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3DB9F10E; Thu, 14 Dec 2023 09:36:26 -0800 (PST) Received: from p-infra-ksmg-sc-msk02 (localhost [127.0.0.1]) by mx1.sberdevices.ru (Postfix) with ESMTP id C789912001A; Thu, 14 Dec 2023 20:36:24 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.sberdevices.ru C789912001A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=salutedevices.com; s=mail; t=1702575384; bh=iVWYFD6b0apij0HQWfsa8gAqaTMVMRAzNodGO05e/bE=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type:From; b=lsJ1+DAjunouTieLbR0DMDE+qCUpL/VIvCKfDxmTxqgWwou1vJgPy5TEMeDUyMY17 rijdruXZjHnokHnmFWKFPBzB5LV7P9oCurhzZ60Nw+yqqWZ9C3tHRZa3LwDAEph44k NY66cZDjQ9h5WfXg5HKOC49axRfnSvsxqWOHfx0Qe1f8r4KR7md8DNONqyH0Wpo586 kdife/rVHy03q5wePcq0d2cJW9uhDVv4BTI5LBVJqOyTt3kHl5W0FJu0urgWbnS4AG Bbx+vxkXBg3cxz3LUaQrntRGI2zqyHxqFJxvqJCXm9pJsWU1qVfjr9owIxDGketVPZ bVNnhzOsyoIlg== Received: from smtp.sberdevices.ru (p-i-exch-sc-m01.sberdevices.ru [172.16.192.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.sberdevices.ru (Postfix) with ESMTPS; Thu, 14 Dec 2023 20:36:24 +0300 (MSK) Received: from localhost.localdomain (100.64.160.123) by p-i-exch-sc-m01.sberdevices.ru (172.16.192.107) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 14 Dec 2023 20:36:24 +0300 From: George Stark <gnstark@salutedevices.com> To: <andy.shevchenko@gmail.com>, <pavel@ucw.cz>, <lee@kernel.org>, <vadimp@nvidia.com>, <mpe@ellerman.id.au>, <npiggin@gmail.com>, <christophe.leroy@csgroup.eu>, <hdegoede@redhat.com>, <mazziesaccount@gmail.com>, <peterz@infradead.org>, <mingo@redhat.com>, <will@kernel.org>, <longman@redhat.com>, <boqun.feng@gmail.com>, <nikitos.tr@gmail.com> CC: <linux-leds@vger.kernel.org>, <linux-kernel@vger.kernel.org>, <linuxppc-dev@lists.ozlabs.org>, <kernel@salutedevices.com>, George Stark <gnstark@salutedevices.com> Subject: [PATCH v4 02/10] locking: introduce devm_mutex_init Date: Thu, 14 Dec 2023 20:36:06 +0300 Message-ID: <20231214173614.2820929-3-gnstark@salutedevices.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231214173614.2820929-1-gnstark@salutedevices.com> References: <20231214173614.2820929-1-gnstark@salutedevices.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [100.64.160.123] X-ClientProxiedBy: p-i-exch-sc-m02.sberdevices.ru (172.16.192.103) To p-i-exch-sc-m01.sberdevices.ru (172.16.192.107) X-KSMG-Rule-ID: 10 X-KSMG-Message-Action: clean X-KSMG-AntiSpam-Lua-Profiles: 182125 [Dec 14 2023] X-KSMG-AntiSpam-Version: 6.1.0.3 X-KSMG-AntiSpam-Envelope-From: gnstark@salutedevices.com X-KSMG-AntiSpam-Rate: 0 X-KSMG-AntiSpam-Status: not_detected X-KSMG-AntiSpam-Method: none X-KSMG-AntiSpam-Auth: dkim=none X-KSMG-AntiSpam-Info: LuaCore: 7 0.3.7 6d6bf5bd8eea7373134f756a2fd73e9456bb7d1a, {Tracking_from_domain_doesnt_match_to}, salutedevices.com:7.1.1;smtp.sberdevices.ru:5.0.1,7.1.1;d41d8cd98f00b204e9800998ecf8427e.com:7.1.1;100.64.160.123:7.1.2;127.0.0.199:7.1.2, FromAlignment: s, ApMailHostAddress: 100.64.160.123 X-MS-Exchange-Organization-SCL: -1 X-KSMG-AntiSpam-Interceptor-Info: scan successful X-KSMG-AntiPhishing: Clean X-KSMG-LinksScanning: Clean X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 2.0.1.6960, bases: 2023/12/14 10:50:00 #22693095 X-KSMG-AntiVirus-Status: Clean, skipped X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on groat.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (groat.vger.email [0.0.0.0]); Thu, 14 Dec 2023 09:36:50 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1785279717476540752 X-GMAIL-MSGID: 1785279717476540752 |
Series |
devm_led_classdev_register() usage problem
|
|
Commit Message
George Stark
Dec. 14, 2023, 5:36 p.m. UTC
Using of devm API leads to a 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() will be
extended so introduce devm_mutex_init()
Signed-off-by: George Stark <gnstark@salutedevices.com>
---
include/linux/mutex.h | 23 +++++++++++++++++++++++
kernel/locking/mutex-debug.c | 22 ++++++++++++++++++++++
2 files changed, 45 insertions(+)
Comments
On 12/14/23 12:36, George Stark wrote: > Using of devm API leads to a 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() will be > extended so introduce devm_mutex_init() > > Signed-off-by: George Stark <gnstark@salutedevices.com> > --- > include/linux/mutex.h | 23 +++++++++++++++++++++++ > kernel/locking/mutex-debug.c | 22 ++++++++++++++++++++++ > 2 files changed, 45 insertions(+) > > diff --git a/include/linux/mutex.h b/include/linux/mutex.h > index a33aa9eb9fc3..ebd03ff1ef66 100644 > --- a/include/linux/mutex.h > +++ b/include/linux/mutex.h > @@ -21,6 +21,8 @@ > #include <linux/debug_locks.h> > #include <linux/cleanup.h> > > +struct device; > + > #ifdef CONFIG_DEBUG_LOCK_ALLOC > # define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ > , .dep_map = { \ > @@ -127,6 +129,20 @@ extern void __mutex_init(struct mutex *lock, const char *name, > */ > extern bool mutex_is_locked(struct mutex *lock); > > +#ifdef CONFIG_DEBUG_MUTEXES > + > +int devm_mutex_init(struct device *dev, struct mutex *lock); Please add "extern" to the function declaration to be consistent with other functional declarations in mutex.h. > + > +#else > + > +static inline int devm_mutex_init(struct device *dev, struct mutex *lock) > +{ > + mutex_init(lock); > + return 0; > +} I would prefer you to add a devm_mutex_init macro after the function declaration and put this inline function at the end of header if the devm_mutex_init macro isn't defined. In this way, you don't need to repeat this inline function twice as it has no dependency on PREEMPT_RT. By doing this, you can also move the function declaration right after mutex_destroy() without the need to add another #ifdef CONFIG_DEBUG_MUTEXES block. > + > +#endif > + > #else /* !CONFIG_PREEMPT_RT */ > /* > * Preempt-RT variant based on rtmutexes. > @@ -169,6 +185,13 @@ do { \ > \ > __mutex_init((mutex), #mutex, &__key); \ > } while (0) > + > +static inline int devm_mutex_init(struct device *dev, struct mutex *lock) > +{ > + mutex_init(lock); > + return 0; > +} > + > #endif /* CONFIG_PREEMPT_RT */ > > /* > diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c > index bc8abb8549d2..c9efab1a8026 100644 > --- a/kernel/locking/mutex-debug.c > +++ b/kernel/locking/mutex-debug.c > @@ -19,6 +19,7 @@ > #include <linux/kallsyms.h> > #include <linux/interrupt.h> > #include <linux/debug_locks.h> > +#include <linux/device.h> > > #include "mutex.h" > > @@ -104,3 +105,24 @@ void mutex_destroy(struct mutex *lock) > } > > EXPORT_SYMBOL_GPL(mutex_destroy); > + > +static void devm_mutex_release(void *res) > +{ > + mutex_destroy(res); > +} > + > +/** > + * devm_mutex_init - Resource-managed mutex initialization > + * @dev: Device which lifetime mutex is bound to > + * @lock: Pointer to a mutex > + * > + * Initialize mutex which is automatically destroyed when the driver is detached. > + * > + * Returns: 0 on success or a negative error code on failure. > + */ > +int devm_mutex_init(struct device *dev, struct mutex *lock) > +{ > + mutex_init(lock); > + return devm_add_action_or_reset(dev, devm_mutex_release, lock); > +} > +EXPORT_SYMBOL_GPL(devm_mutex_init); The mutex-debug.c change looks fine to me. Cheers, Longman
Le 14/12/2023 à 18:36, George Stark a écrit : > [Vous ne recevez pas souvent de courriers de gnstark@salutedevices.com. Découvrez pourquoi ceci est important à https://aka.ms/LearnAboutSenderIdentification ] > > Using of devm API leads to a 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() will be > extended so introduce devm_mutex_init() > > Signed-off-by: George Stark <gnstark@salutedevices.com> > --- > include/linux/mutex.h | 23 +++++++++++++++++++++++ > kernel/locking/mutex-debug.c | 22 ++++++++++++++++++++++ > 2 files changed, 45 insertions(+) > > diff --git a/include/linux/mutex.h b/include/linux/mutex.h > index a33aa9eb9fc3..ebd03ff1ef66 100644 > --- a/include/linux/mutex.h > +++ b/include/linux/mutex.h > @@ -21,6 +21,8 @@ > #include <linux/debug_locks.h> > #include <linux/cleanup.h> > > +struct device; > + > #ifdef CONFIG_DEBUG_LOCK_ALLOC > # define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ > , .dep_map = { \ > @@ -127,6 +129,20 @@ extern void __mutex_init(struct mutex *lock, const char *name, > */ > extern bool mutex_is_locked(struct mutex *lock); > > +#ifdef CONFIG_DEBUG_MUTEXES > + > +int devm_mutex_init(struct device *dev, struct mutex *lock); > + > +#else > + > +static inline int devm_mutex_init(struct device *dev, struct mutex *lock) > +{ > + mutex_init(lock); > + return 0; > +} > + > +#endif > + > #else /* !CONFIG_PREEMPT_RT */ > /* > * Preempt-RT variant based on rtmutexes. > @@ -169,6 +185,13 @@ do { \ > \ > __mutex_init((mutex), #mutex, &__key); \ > } while (0) > + > +static inline int devm_mutex_init(struct device *dev, struct mutex *lock) > +{ > + mutex_init(lock); > + return 0; > +} > + > #endif /* CONFIG_PREEMPT_RT */ > > /* > diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c > index bc8abb8549d2..c9efab1a8026 100644 > --- a/kernel/locking/mutex-debug.c > +++ b/kernel/locking/mutex-debug.c > @@ -19,6 +19,7 @@ > #include <linux/kallsyms.h> > #include <linux/interrupt.h> > #include <linux/debug_locks.h> > +#include <linux/device.h> > > #include "mutex.h" > > @@ -104,3 +105,24 @@ void mutex_destroy(struct mutex *lock) > } > > EXPORT_SYMBOL_GPL(mutex_destroy); > + > +static void devm_mutex_release(void *res) > +{ > + mutex_destroy(res); > +} > + > +/** > + * devm_mutex_init - Resource-managed mutex initialization > + * @dev: Device which lifetime mutex is bound to > + * @lock: Pointer to a mutex > + * > + * Initialize mutex which is automatically destroyed when the driver is detached. > + * > + * Returns: 0 on success or a negative error code on failure. > + */ > +int devm_mutex_init(struct device *dev, struct mutex *lock) > +{ > + mutex_init(lock); > + return devm_add_action_or_reset(dev, devm_mutex_release, lock); > +} > +EXPORT_SYMBOL_GPL(devm_mutex_init); > -- > 2.25.1 > I think it would make sense to keep mutex_destroy() and devm_mutex_init() together, see exemple below: diff --git a/include/linux/mutex.h b/include/linux/mutex.h index ebd03ff1ef66..c620759ff85b 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h @@ -83,14 +83,10 @@ struct mutex { #define __DEBUG_MUTEX_INITIALIZER(lockname) \ , .magic = &lockname -extern void mutex_destroy(struct mutex *lock); - #else # define __DEBUG_MUTEX_INITIALIZER(lockname) -static inline void mutex_destroy(struct mutex *lock) {} - #endif /** @@ -131,10 +127,13 @@ extern bool mutex_is_locked(struct mutex *lock); #ifdef CONFIG_DEBUG_MUTEXES +void mutex_destroy(struct mutex *lock); int devm_mutex_init(struct device *dev, struct mutex *lock); #else +static inline void mutex_destroy(struct mutex *lock) {} + static inline int devm_mutex_init(struct device *dev, struct mutex *lock) { mutex_init(lock); @@ -169,8 +168,6 @@ extern void __mutex_rt_init(struct mutex *lock, const char *name, struct lock_class_key *key); extern int mutex_trylock(struct mutex *lock); -static inline void mutex_destroy(struct mutex *lock) { } - #define mutex_is_locked(l) rt_mutex_base_is_locked(&(l)->rtmutex) #define __mutex_init(mutex, name, key) \ @@ -186,6 +183,8 @@ do { \ __mutex_init((mutex), #mutex, &__key); \ } while (0) +static inline void mutex_destroy(struct mutex *lock) { } + static inline int devm_mutex_init(struct device *dev, struct mutex *lock) { mutex_init(lock); --- Would also be nice to have a comment explaining that when mutex_destroy() is a nop, devm_mutext_init() doesn't need to register a release function. Either way, Reviewed-by: christophe.leroy@csgroup.eu
Le 14/12/2023 à 19:48, Waiman Long a écrit : > > On 12/14/23 12:36, George Stark wrote: >> Using of devm API leads to a 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() will be >> extended so introduce devm_mutex_init() >> >> Signed-off-by: George Stark <gnstark@salutedevices.com> >> --- >> include/linux/mutex.h | 23 +++++++++++++++++++++++ >> kernel/locking/mutex-debug.c | 22 ++++++++++++++++++++++ >> 2 files changed, 45 insertions(+) >> >> diff --git a/include/linux/mutex.h b/include/linux/mutex.h >> index a33aa9eb9fc3..ebd03ff1ef66 100644 >> --- a/include/linux/mutex.h >> +++ b/include/linux/mutex.h >> @@ -21,6 +21,8 @@ >> #include <linux/debug_locks.h> >> #include <linux/cleanup.h> >> +struct device; >> + >> #ifdef CONFIG_DEBUG_LOCK_ALLOC >> # define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ >> , .dep_map = { \ >> @@ -127,6 +129,20 @@ extern void __mutex_init(struct mutex *lock, >> const char *name, >> */ >> extern bool mutex_is_locked(struct mutex *lock); >> +#ifdef CONFIG_DEBUG_MUTEXES >> + >> +int devm_mutex_init(struct device *dev, struct mutex *lock); > Please add "extern" to the function declaration to be consistent with > other functional declarations in mutex.h. 'extern' is pointless and deprecated on function prototypes. Already having some is not a good reason to add new ones, errors from the past should be avoided nowadays. With time they should all disappear so don't add new ones. >> + >> +#else >> + >> +static inline int devm_mutex_init(struct device *dev, struct mutex >> *lock) >> +{ >> + mutex_init(lock); >> + return 0; >> +} > > I would prefer you to add a devm_mutex_init macro after the function > declaration and put this inline function at the end of header if the > devm_mutex_init macro isn't defined. In this way, you don't need to > repeat this inline function twice as it has no dependency on PREEMPT_RT. It is already done that way for other functions in that file. Should be kept consistant. I agree with you it is not ideal, maybe we should rework that file completely but I don't like the idea of a devm_mutex_init macro for that. Christophe > > By doing this, you can also move the function declaration right after > mutex_destroy() without the need to add another #ifdef > CONFIG_DEBUG_MUTEXES block. > >> + >> +#endif >> + >> #else /* !CONFIG_PREEMPT_RT */ >> /* >> * Preempt-RT variant based on rtmutexes. >> @@ -169,6 +185,13 @@ do { \ >> \ >> __mutex_init((mutex), #mutex, &__key); \ >> } while (0) >> + >> +static inline int devm_mutex_init(struct device *dev, struct mutex >> *lock) >> +{ >> + mutex_init(lock); >> + return 0; >> +} >> + >> #endif /* CONFIG_PREEMPT_RT */ >> /* >> diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c >> index bc8abb8549d2..c9efab1a8026 100644 >> --- a/kernel/locking/mutex-debug.c >> +++ b/kernel/locking/mutex-debug.c >> @@ -19,6 +19,7 @@ >> #include <linux/kallsyms.h> >> #include <linux/interrupt.h> >> #include <linux/debug_locks.h> >> +#include <linux/device.h> >> #include "mutex.h" >> @@ -104,3 +105,24 @@ void mutex_destroy(struct mutex *lock) >> } >> EXPORT_SYMBOL_GPL(mutex_destroy); >> + >> +static void devm_mutex_release(void *res) >> +{ >> + mutex_destroy(res); >> +} >> + >> +/** >> + * devm_mutex_init - Resource-managed mutex initialization >> + * @dev: Device which lifetime mutex is bound to >> + * @lock: Pointer to a mutex >> + * >> + * Initialize mutex which is automatically destroyed when the driver >> is detached. >> + * >> + * Returns: 0 on success or a negative error code on failure. >> + */ >> +int devm_mutex_init(struct device *dev, struct mutex *lock) >> +{ >> + mutex_init(lock); >> + return devm_add_action_or_reset(dev, devm_mutex_release, lock); >> +} >> +EXPORT_SYMBOL_GPL(devm_mutex_init); > > The mutex-debug.c change looks fine to me. > > Cheers, > Longman > >
On 12/14/23 14:53, Christophe Leroy wrote: > > Le 14/12/2023 à 19:48, Waiman Long a écrit : >> On 12/14/23 12:36, George Stark wrote: >>> Using of devm API leads to a 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() will be >>> extended so introduce devm_mutex_init() >>> >>> Signed-off-by: George Stark <gnstark@salutedevices.com> >>> --- >>> include/linux/mutex.h | 23 +++++++++++++++++++++++ >>> kernel/locking/mutex-debug.c | 22 ++++++++++++++++++++++ >>> 2 files changed, 45 insertions(+) >>> >>> diff --git a/include/linux/mutex.h b/include/linux/mutex.h >>> index a33aa9eb9fc3..ebd03ff1ef66 100644 >>> --- a/include/linux/mutex.h >>> +++ b/include/linux/mutex.h >>> @@ -21,6 +21,8 @@ >>> #include <linux/debug_locks.h> >>> #include <linux/cleanup.h> >>> +struct device; >>> + >>> #ifdef CONFIG_DEBUG_LOCK_ALLOC >>> # define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ >>> , .dep_map = { \ >>> @@ -127,6 +129,20 @@ extern void __mutex_init(struct mutex *lock, >>> const char *name, >>> */ >>> extern bool mutex_is_locked(struct mutex *lock); >>> +#ifdef CONFIG_DEBUG_MUTEXES >>> + >>> +int devm_mutex_init(struct device *dev, struct mutex *lock); >> Please add "extern" to the function declaration to be consistent with >> other functional declarations in mutex.h. > 'extern' is pointless and deprecated on function prototypes. Already > having some is not a good reason to add new ones, errors from the past > should be avoided nowadays. With time they should all disappear so don't > add new ones. Yes, "extern" is optional. It is just a suggestion and I am going to argue about that. > >>> + >>> +#else >>> + >>> +static inline int devm_mutex_init(struct device *dev, struct mutex >>> *lock) >>> +{ >>> + mutex_init(lock); >>> + return 0; >>> +} >> I would prefer you to add a devm_mutex_init macro after the function >> declaration and put this inline function at the end of header if the >> devm_mutex_init macro isn't defined. In this way, you don't need to >> repeat this inline function twice as it has no dependency on PREEMPT_RT. > It is already done that way for other functions in that file. Should be > kept consistant. I agree with you it is not ideal, maybe we should > rework that file completely but I don't like the idea of a > devm_mutex_init macro for that. devm_mutex_init() is not an API for the core mutex code. That is why I want to minimize change to the existing code layout. Putting it at the end will reduce confusion when developers look up mutex.h header file to find out what mutex functions are available. Cheers, Longman
Le 14/12/2023 à 22:48, Waiman Long a écrit : > On 12/14/23 14:53, Christophe Leroy wrote: >> >> Le 14/12/2023 à 19:48, Waiman Long a écrit : >>> On 12/14/23 12:36, George Stark wrote: >>>> Using of devm API leads to a 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() will be >>>> extended so introduce devm_mutex_init() >>>> >>>> Signed-off-by: George Stark <gnstark@salutedevices.com> >>>> --- >>>> include/linux/mutex.h | 23 +++++++++++++++++++++++ >>>> kernel/locking/mutex-debug.c | 22 ++++++++++++++++++++++ >>>> 2 files changed, 45 insertions(+) >>>> >>>> diff --git a/include/linux/mutex.h b/include/linux/mutex.h >>>> index a33aa9eb9fc3..ebd03ff1ef66 100644 >>>> --- a/include/linux/mutex.h >>>> +++ b/include/linux/mutex.h >>>> @@ -21,6 +21,8 @@ >>>> #include <linux/debug_locks.h> >>>> #include <linux/cleanup.h> >>>> +struct device; >>>> + >>>> #ifdef CONFIG_DEBUG_LOCK_ALLOC >>>> # define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ >>>> , .dep_map = { \ >>>> @@ -127,6 +129,20 @@ extern void __mutex_init(struct mutex *lock, >>>> const char *name, >>>> */ >>>> extern bool mutex_is_locked(struct mutex *lock); >>>> +#ifdef CONFIG_DEBUG_MUTEXES >>>> + >>>> +int devm_mutex_init(struct device *dev, struct mutex *lock); >>> Please add "extern" to the function declaration to be consistent with >>> other functional declarations in mutex.h. >> 'extern' is pointless and deprecated on function prototypes. Already >> having some is not a good reason to add new ones, errors from the past >> should be avoided nowadays. With time they should all disappear so don't >> add new ones. > Yes, "extern" is optional. It is just a suggestion and I am going to > argue about that. FWIW, note that when you perform a strict check with checkpatch.pl, you get a warning for that: $ ./scripts/checkpatch.pl --strict -g HEAD CHECK: extern prototypes should be avoided in .h files #56: FILE: include/linux/mutex.h:131: +extern int devm_mutex_init(struct device *dev, struct mutex *lock); total: 0 errors, 0 warnings, 1 checks, 99 lines checked >> >>>> + >>>> +#else >>>> + >>>> +static inline int devm_mutex_init(struct device *dev, struct mutex >>>> *lock) >>>> +{ >>>> + mutex_init(lock); >>>> + return 0; >>>> +} >>> I would prefer you to add a devm_mutex_init macro after the function >>> declaration and put this inline function at the end of header if the >>> devm_mutex_init macro isn't defined. In this way, you don't need to >>> repeat this inline function twice as it has no dependency on PREEMPT_RT. >> It is already done that way for other functions in that file. Should be >> kept consistant. I agree with you it is not ideal, maybe we should >> rework that file completely but I don't like the idea of a >> devm_mutex_init macro for that. > > devm_mutex_init() is not an API for the core mutex code. That is why I > want to minimize change to the existing code layout. Putting it at the > end will reduce confusion when developers look up mutex.h header file to > find out what mutex functions are available. If I look at linux/gpio.h we are more or less in the same situation I think. devm_mutex_init() is not an API for the core mutex code, but developers need to know the managed functions for mutex exist, and having them at the same place as non managed functions looks better to me. Now I agree with you that this duplication of functions is not the best, and it also applies to existing content of mutex.h so maybe we can do something about it later and improve the situation. Christophe
Le 15/12/2023 à 16:58, Andy Shevchenko a écrit : > On Fri, Dec 15, 2023 at 8:23 AM Christophe Leroy > <christophe.leroy@csgroup.eu> wrote: >> >> From: George Stark <gnstark@salutedevices.com> >> >> Using of devm API leads to a 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() will be >> extended so introduce devm_mutex_init() > > Missing period. > > ... > >> } while (0) >> #endif /* CONFIG_PREEMPT_RT */ > > ^^^ (1) > >> +struct device; >> + >> +/* >> + * devm_mutex_init() registers a function that calls mutex_destroy() >> + * when the ressource is released. >> + * >> + * When mutex_destroy() is a not, there is no need to register that >> + * function. >> + */ >> +#ifdef CONFIG_DEBUG_MUTEXES > > Shouldn't this be > > #if defined(CONFIG_DEBUG_MUTEXES) && !defined(CONFIG_PREEMPT_RT) > > (see (1) as well)? Isn't needed, handled by Kconfig: config DEBUG_MUTEXES bool "Mutex debugging: basic checks" depends on DEBUG_KERNEL && !PREEMPT_RT > >> +void mutex_destroy(struct mutex *lock); >> +int devm_mutex_init(struct device *dev, struct mutex *lock); >> +#else >> +static inline void mutex_destroy(struct mutex *lock) {} >> + >> +static inline int devm_mutex_init(struct device *dev, struct mutex *lock) >> +{ >> + mutex_init(lock); >> + return 0; >> +} >> +#endif >
On 12/15/23 10:58, Andy Shevchenko wrote: > On Fri, Dec 15, 2023 at 8:23 AM Christophe Leroy > <christophe.leroy@csgroup.eu> wrote: >> From: George Stark <gnstark@salutedevices.com> >> >> Using of devm API leads to a 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() will be >> extended so introduce devm_mutex_init() > Missing period. > > ... > >> } while (0) >> #endif /* CONFIG_PREEMPT_RT */ > ^^^ (1) > >> +struct device; >> + >> +/* >> + * devm_mutex_init() registers a function that calls mutex_destroy() >> + * when the ressource is released. >> + * >> + * When mutex_destroy() is a not, there is no need to register that >> + * function. >> + */ >> +#ifdef CONFIG_DEBUG_MUTEXES > Shouldn't this be > > #if defined(CONFIG_DEBUG_MUTEXES) && !defined(CONFIG_PREEMPT_RT) > > (see (1) as well)? CONFIG_DEBUG_MUTEXES and CONFIG_PREEMPT_RT are mutually exclusive. At most one of them can be set. Cheers, Longman
Hello Christophe On 12/15/23 08:46, Christophe Leroy wrote: > > > Le 14/12/2023 à 22:48, Waiman Long a écrit : >> On 12/14/23 14:53, Christophe Leroy wrote: >>> >>> Le 14/12/2023 à 19:48, Waiman Long a écrit : >>>> On 12/14/23 12:36, George Stark wrote: >>>>> Using of devm API leads to a 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() will be >>>>> extended so introduce devm_mutex_init() >>>>> >>>>> Signed-off-by: George Stark <gnstark@salutedevices.com> >>>>> --- >>>>> include/linux/mutex.h | 23 +++++++++++++++++++++++ >>>>> kernel/locking/mutex-debug.c | 22 ++++++++++++++++++++++ >>>>> 2 files changed, 45 insertions(+) >>>>> >>>>> diff --git a/include/linux/mutex.h b/include/linux/mutex.h >>>>> index a33aa9eb9fc3..ebd03ff1ef66 100644 >>>>> --- a/include/linux/mutex.h >>>>> +++ b/include/linux/mutex.h >>>>> @@ -21,6 +21,8 @@ >>>>> #include <linux/debug_locks.h> >>>>> #include <linux/cleanup.h> >>>>> +struct device; >>>>> + >>>>> #ifdef CONFIG_DEBUG_LOCK_ALLOC >>>>> # define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ >>>>> , .dep_map = { \ >>>>> @@ -127,6 +129,20 @@ extern void __mutex_init(struct mutex *lock, >>>>> const char *name, >>>>> */ >>>>> extern bool mutex_is_locked(struct mutex *lock); >>>>> +#ifdef CONFIG_DEBUG_MUTEXES >>>>> + >>>>> +int devm_mutex_init(struct device *dev, struct mutex *lock); >>>> Please add "extern" to the function declaration to be consistent with >>>> other functional declarations in mutex.h. >>> 'extern' is pointless and deprecated on function prototypes. Already >>> having some is not a good reason to add new ones, errors from the past >>> should be avoided nowadays. With time they should all disappear so don't >>> add new ones. >> Yes, "extern" is optional. It is just a suggestion and I am going to >> argue about that. > > FWIW, note that when you perform a strict check with checkpatch.pl, you > get a warning for that: > > $ ./scripts/checkpatch.pl --strict -g HEAD > CHECK: extern prototypes should be avoided in .h files > #56: FILE: include/linux/mutex.h:131: > +extern int devm_mutex_init(struct device *dev, struct mutex *lock); > > total: 0 errors, 0 warnings, 1 checks, 99 lines checked This is ambiguous situation about extern. It's deprecated and useless on one hand but harmless. And those externs will not disappear by themself - it'll be one patch that clean them all at once (in one header at least) so one more extern will not alter the overall picture. On the other hand if we manage to place devm_mutex_init near mutex_destroy then we'll have: int devm_mutex_init(struct device *dev, struct mutex *lock); extern void mutex_destroy(struct mutex *lock); and it raises questions and does not look very nice. >>> >>>>> + >>>>> +#else >>>>> + >>>>> +static inline int devm_mutex_init(struct device *dev, struct mutex >>>>> *lock) >>>>> +{ >>>>> + mutex_init(lock); >>>>> + return 0; >>>>> +} >>>> I would prefer you to add a devm_mutex_init macro after the function >>>> declaration and put this inline function at the end of header if the >>>> devm_mutex_init macro isn't defined. In this way, you don't need to >>>> repeat this inline function twice as it has no dependency on PREEMPT_RT. >>> It is already done that way for other functions in that file. Should be >>> kept consistant. I agree with you it is not ideal, maybe we should >>> rework that file completely but I don't like the idea of a >>> devm_mutex_init macro for that. >> >> devm_mutex_init() is not an API for the core mutex code. That is why I >> want to minimize change to the existing code layout. Putting it at the >> end will reduce confusion when developers look up mutex.h header file to >> find out what mutex functions are available. > > If I look at linux/gpio.h we are more or less in the same situation I think. > > devm_mutex_init() is not an API for the core mutex code, but developers > need to know the managed functions for mutex exist, and having them at > the same place as non managed functions looks better to me. Now I agree > with you that this duplication of functions is not the best, and it also > applies to existing content of mutex.h so maybe we can do something > about it later and improve the situation. > > Christophe
Le 17/12/2023 à 02:05, George Stark a écrit : > [Vous ne recevez pas souvent de courriers de gnstark@salutedevices.com. > Découvrez pourquoi ceci est important à > https://aka.ms/LearnAboutSenderIdentification ] > > Hello Christophe > > On 12/15/23 08:46, Christophe Leroy wrote: >> >> >> Le 14/12/2023 à 22:48, Waiman Long a écrit : >>> On 12/14/23 14:53, Christophe Leroy wrote: >>>> >>>> Le 14/12/2023 à 19:48, Waiman Long a écrit : >>>>> On 12/14/23 12:36, George Stark wrote: >>>>>> Using of devm API leads to a 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() >>>>>> will be >>>>>> extended so introduce devm_mutex_init() >>>>>> >>>>>> Signed-off-by: George Stark <gnstark@salutedevices.com> >>>>>> --- >>>>>> include/linux/mutex.h | 23 +++++++++++++++++++++++ >>>>>> kernel/locking/mutex-debug.c | 22 ++++++++++++++++++++++ >>>>>> 2 files changed, 45 insertions(+) >>>>>> >>>>>> diff --git a/include/linux/mutex.h b/include/linux/mutex.h >>>>>> index a33aa9eb9fc3..ebd03ff1ef66 100644 >>>>>> --- a/include/linux/mutex.h >>>>>> +++ b/include/linux/mutex.h >>>>>> @@ -21,6 +21,8 @@ >>>>>> #include <linux/debug_locks.h> >>>>>> #include <linux/cleanup.h> >>>>>> +struct device; >>>>>> + >>>>>> #ifdef CONFIG_DEBUG_LOCK_ALLOC >>>>>> # define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ >>>>>> , .dep_map = { \ >>>>>> @@ -127,6 +129,20 @@ extern void __mutex_init(struct mutex *lock, >>>>>> const char *name, >>>>>> */ >>>>>> extern bool mutex_is_locked(struct mutex *lock); >>>>>> +#ifdef CONFIG_DEBUG_MUTEXES >>>>>> + >>>>>> +int devm_mutex_init(struct device *dev, struct mutex *lock); >>>>> Please add "extern" to the function declaration to be consistent with >>>>> other functional declarations in mutex.h. >>>> 'extern' is pointless and deprecated on function prototypes. Already >>>> having some is not a good reason to add new ones, errors from the past >>>> should be avoided nowadays. With time they should all disappear so >>>> don't >>>> add new ones. >>> Yes, "extern" is optional. It is just a suggestion and I am going to >>> argue about that. >> >> FWIW, note that when you perform a strict check with checkpatch.pl, you >> get a warning for that: >> >> $ ./scripts/checkpatch.pl --strict -g HEAD >> CHECK: extern prototypes should be avoided in .h files >> #56: FILE: include/linux/mutex.h:131: >> +extern int devm_mutex_init(struct device *dev, struct mutex *lock); >> >> total: 0 errors, 0 warnings, 1 checks, 99 lines checked > > This is ambiguous situation about extern. It's deprecated and useless on > one hand but harmless. And those externs will not disappear by themself > - it'll be one patch that clean them all at once (in one header at > least) so one more extern will not alter the overall picture. That kind of cleanup patch bomb is a nightmare for backporting, so if it happens one day it should be as light as possible, hence the importance to not add new ones and remove existing one everytime you modify or move a line including it for whatever reason. > > On the other hand if we manage to place devm_mutex_init near > mutex_destroy then we'll have: > > int devm_mutex_init(struct device *dev, struct mutex *lock); > extern void mutex_destroy(struct mutex *lock); I sent you an alternative proposal that avoids duplication of the static inline version of devm_mutex_init(). If you agree with it just take it into your series and that question will vanish. > > and it raises questions and does not look very nice. If you look at linux/mm.h there are plenty of them anyway, so why do different ? For an exemple look at https://elixir.bootlin.com/linux/v6.7-rc4/source/include/linux/mm.h#L2372 Christophe
diff --git a/include/linux/mutex.h b/include/linux/mutex.h index a33aa9eb9fc3..ebd03ff1ef66 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h @@ -21,6 +21,8 @@ #include <linux/debug_locks.h> #include <linux/cleanup.h> +struct device; + #ifdef CONFIG_DEBUG_LOCK_ALLOC # define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ , .dep_map = { \ @@ -127,6 +129,20 @@ extern void __mutex_init(struct mutex *lock, const char *name, */ extern bool mutex_is_locked(struct mutex *lock); +#ifdef CONFIG_DEBUG_MUTEXES + +int devm_mutex_init(struct device *dev, struct mutex *lock); + +#else + +static inline int devm_mutex_init(struct device *dev, struct mutex *lock) +{ + mutex_init(lock); + return 0; +} + +#endif + #else /* !CONFIG_PREEMPT_RT */ /* * Preempt-RT variant based on rtmutexes. @@ -169,6 +185,13 @@ do { \ \ __mutex_init((mutex), #mutex, &__key); \ } while (0) + +static inline int devm_mutex_init(struct device *dev, struct mutex *lock) +{ + mutex_init(lock); + return 0; +} + #endif /* CONFIG_PREEMPT_RT */ /* diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c index bc8abb8549d2..c9efab1a8026 100644 --- a/kernel/locking/mutex-debug.c +++ b/kernel/locking/mutex-debug.c @@ -19,6 +19,7 @@ #include <linux/kallsyms.h> #include <linux/interrupt.h> #include <linux/debug_locks.h> +#include <linux/device.h> #include "mutex.h" @@ -104,3 +105,24 @@ void mutex_destroy(struct mutex *lock) } EXPORT_SYMBOL_GPL(mutex_destroy); + +static void devm_mutex_release(void *res) +{ + mutex_destroy(res); +} + +/** + * devm_mutex_init - Resource-managed mutex initialization + * @dev: Device which lifetime mutex is bound to + * @lock: Pointer to a mutex + * + * Initialize mutex which is automatically destroyed when the driver is detached. + * + * Returns: 0 on success or a negative error code on failure. + */ +int devm_mutex_init(struct device *dev, struct mutex *lock) +{ + mutex_init(lock); + return devm_add_action_or_reset(dev, devm_mutex_release, lock); +} +EXPORT_SYMBOL_GPL(devm_mutex_init);