All of lore.kernel.org
 help / color / mirror / Atom feed
From: <dan.j.williams@intel.com>
To: Peter Zijlstra <peterz@infradead.org>,
	Dan Williams <dan.j.williams@intel.com>
Cc: <linux-cxl@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	David Lechner <dlechner@baylibre.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	"Ingo Molnar" <mingo@kernel.org>,
	"Fabio M. De Francesco"
	<fabio.maria.de.francesco@linux.intel.com>,
	Davidlohr Bueso <dave@stgolabs.net>,
	Jonathan Cameron <jonathan.cameron@huawei.com>,
	"Dave Jiang" <dave.jiang@intel.com>,
	Alison Schofield <alison.schofield@intel.com>,
	Vishal Verma <vishal.l.verma@intel.com>,
	Ira Weiny <ira.weiny@intel.com>
Subject: Re: [PATCH 1/7] cleanup: Introduce DEFINE_ACQUIRE() a CLASS() for conditional locking
Date: Fri, 9 May 2025 18:11:49 -0700	[thread overview]
Message-ID: <681ea7d5ea04b_2a2bb100cf@dwillia2-mobl4.notmuch> (raw)
In-Reply-To: <20250509104028.GL4439@noisy.programming.kicks-ass.net>

Peter Zijlstra wrote:
> On Thu, May 08, 2025 at 10:04:32PM -0700, Dan Williams wrote:
> > Peter Zijlstra wrote:
> > [..]
> > > > So the proposal is, if you know what you are doing, or have a need to
> > > > switch back and forth between scope-based and explicit unlock for a give
> > > > lock, use the base primitives. If instead you want to fully convert to
> > > > scope-based lock management (excise all explicit unlock() calls) *and*
> > > > you want the compiler to validate the conversion, switch to the _acquire
> > > > parallel universe.
> > > 
> > > As with all refactoring ever, the rename trick always works. But I don't
> > > think that warrants building a parallel infrastructure just for that.
> > > 
> > > Specifically, it very much does not disallow calling mutex_unlock() on
> > > your new member. So all you get is some compiler help during refactor,
> > > and again, just rename the lock member already.
> > > 
> > > Also, if we ever actually get LLVM's Thread Safety Analysis working,
> > > that will help us with all these problems:
> > > 
> > >   https://lore.kernel.org/all/20250304092417.2873893-1-elver@google.com/
> > 
> > That looks lovely.
> > 
> > > But the compiler needs a little more work go grok C :-)
> > 
> > Ok, here is a last shot that incorporates all the feedback:
> > 
> > 1/ Conceptually no need for a new CLASS() save for the fact that
> >    __guard_ptr() returns NULL on failure, not an ERR_PTR().
> > 
> > 2/ The rename trick is not true type safety, especially if it leads to
> >    parallel universe of primitives, but it is a useful trick.
> > 
> > 3/ "IS_ERR(__guard_ptr(mutex_intr)(lock))" is a mouthful, would be nice
> >    to have something more succint while maintaining some safety.
> > 
> > That leads me to a scheme like the following:
> > 
> >     DEFINE_GUARD_ERR(mutex, _intr, mutex_lock_interruptible(_T))
> >     ...
> >     ACQUIRE(mutex_intr, lock)(&obj->lock);
> >     if (IS_ERR(lock))
> >        return PTR_ERR(lock);
> 
> Urgh.. can you live with something like this?
> 
> ---
> diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
> index d72764056ce6..6b0ca400b393 100644
> --- a/drivers/cxl/core/mbox.c
> +++ b/drivers/cxl/core/mbox.c
> @@ -1394,8 +1394,8 @@ int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len,
>  	int nr_records = 0;
>  	int rc;
>  
> -	rc = mutex_lock_interruptible(&mds->poison.lock);
> -	if (rc)
> +	ACQUIRE(mutex_intr, lock)(&mds->poison.poison_lock);
> +	if ((rc = ACQUIRE_ERR(mutex_intr, &lock)))
>  		return rc;

Yes, I can live with that, and I like the compactness of the resulting
cleanup.h macros better than my attempt.

Although, how about this small ergonomic fixup for more symmetry between
ACQUIRE() and ACQUIRE_ERR()?

---
diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
index 6b0ca400b393..e5d2171c9a48 100644
--- a/drivers/cxl/core/mbox.c
+++ b/drivers/cxl/core/mbox.c
@@ -1395,7 +1395,7 @@ int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len,
 	int rc;
 
 	ACQUIRE(mutex_intr, lock)(&mds->poison.poison_lock);
-	if ((rc = ACQUIRE_ERR(mutex_intr, &lock)))
+	if ((rc = ACQUIRE_ERR(mutex_intr, lock)))
 		return rc;
 
 	po = mds->poison.list_out;
diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h
index 17d4655a6b73..b379ff445179 100644
--- a/include/linux/cleanup.h
+++ b/include/linux/cleanup.h
@@ -335,7 +342,7 @@ static __maybe_unused const bool class_##_name##_is_conditional = _is_cond
 	CLASS(_name, _var)
 
 #define ACQUIRE_ERR(_name, _var) \
-	({ long _rc = PTR_ERR(__guard_ptr(_name)(_var)); \
+	({ long _rc = PTR_ERR(__guard_ptr(_name)(&(_var))); \
 	   if (!_rc) _rc = -EBUSY; \
 	   if (!IS_ERR_VALUE(_rc)) _rc = 0; \
 	   _rc; })


---

Also, I needed the following to get this to compile:

---

diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h
index 17d4655a6b73..052bbad6ac68 100644
--- a/include/linux/cleanup.h
+++ b/include/linux/cleanup.h
@@ -305,8 +305,15 @@ static __maybe_unused const bool class_##_name##_is_conditional = _is_cond
 	__DEFINE_CLASS_IS_CONDITIONAL(_name, true); \
 	__DEFINE_GUARD_LOCK_PTR(_name, _T)
 
+/*
+ * For guard with a potential percpu lock, the address space needs to be
+ * cast away.
+ */
+#define IS_ERR_OR_NULL_ANY(x) \
+IS_ERR_OR_NULL((const void *)(__force const unsigned long)(x))
+
 #define DEFINE_GUARD(_name, _type, _lock, _unlock) \
-	DEFINE_CLASS(_name, _type, if (!IS_ERR_OR_NULL(_T)) { _unlock; }, ({ _lock; _T; }), _type _T); \
+	DEFINE_CLASS(_name, _type, if (!IS_ERR_OR_NULL_ANY(_T)) { _unlock; }, ({ _lock; _T; }), _type _T); \
 	DEFINE_CLASS_IS_GUARD(_name)
 
 #define DEFINE_GUARD_COND_4(_name, _ext, _lock, _cond) \
@@ -401,7 +408,7 @@ typedef struct {							\
 									\
 static inline void class_##_name##_destructor(class_##_name##_t *_T)	\
 {									\
-	if (!IS_ERR_OR_NULL(_T->lock)) { _unlock; }			\
+	if (!IS_ERR_OR_NULL_ANY(_T->lock)) { _unlock; }			\
 }									\
 									\
 __DEFINE_GUARD_LOCK_PTR(_name, &_T->lock)

  reply	other threads:[~2025-05-10  1:12 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-07  7:21 [PATCH 0/7] Introduce DEFINE_ACQUIRE(), a scoped_cond_guard() replacement Dan Williams
2025-05-07  7:21 ` [PATCH 1/7] cleanup: Introduce DEFINE_ACQUIRE() a CLASS() for conditional locking Dan Williams
2025-05-07  9:32   ` Peter Zijlstra
2025-05-07 21:18     ` Dan Williams
2025-05-08 11:00       ` Peter Zijlstra
2025-05-09  5:04         ` Dan Williams
2025-05-09 10:40           ` Peter Zijlstra
2025-05-10  1:11             ` dan.j.williams [this message]
2025-05-12 10:50               ` Peter Zijlstra
2025-05-12 18:25                 ` Peter Zijlstra
2025-05-12 18:58                   ` Peter Zijlstra
2025-05-12 20:39                     ` Linus Torvalds
2025-05-13  7:09                       ` Peter Zijlstra
2025-05-13  8:50                         ` Peter Zijlstra
2025-05-13 19:46                           ` Linus Torvalds
2025-05-13 20:06                             ` Al Viro
2025-05-13 20:31                               ` Al Viro
2025-05-13 21:28                                 ` Linus Torvalds
2025-05-17  9:17                                   ` David Laight
2025-05-14  6:46                             ` Peter Zijlstra
2025-05-13  3:32                     ` dan.j.williams
2025-05-09 19:10   ` kernel test robot
2025-05-07  7:21 ` [PATCH 2/7] cxl/decoder: Move decoder register programming to a helper Dan Williams
2025-05-07  7:21 ` [PATCH 3/7] cxl/decoder: Drop pointless locking Dan Williams
2025-05-07  7:21 ` [PATCH 4/7] cxl/region: Split commit_store() into __commit() and queue_reset() helpers Dan Williams
2025-05-07  7:21 ` [PATCH 5/7] cxl/region: Move ready-to-probe state check to a helper Dan Williams
2025-05-07  7:21 ` [PATCH 6/7] cxl/region: Introduce CLASS(cxl_decoder_detach...) consolidate multiple paths Dan Williams
2025-05-08  7:44   ` kernel test robot
2025-05-07  7:21 ` [PATCH 7/7] cleanup: Create an rwsem conditional acquisition class Dan Williams

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=681ea7d5ea04b_2a2bb100cf@dwillia2-mobl4.notmuch \
    --to=dan.j.williams@intel.com \
    --cc=alison.schofield@intel.com \
    --cc=dave.jiang@intel.com \
    --cc=dave@stgolabs.net \
    --cc=dlechner@baylibre.com \
    --cc=fabio.maria.de.francesco@linux.intel.com \
    --cc=ira.weiny@intel.com \
    --cc=jonathan.cameron@huawei.com \
    --cc=linux-cxl@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=torvalds@linux-foundation.org \
    --cc=vishal.l.verma@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.