All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2 v4] Add cond_guard() to conditional guards
@ 2024-02-08 13:04 Fabio M. De Francesco
  2024-02-08 13:04 ` [PATCH 1/2 v4] cleanup: " Fabio M. De Francesco
  2024-02-08 13:04 ` [PATCH 2/2 v4] cxl/region: Use cond_guard() in show_targetN() Fabio M. De Francesco
  0 siblings, 2 replies; 9+ messages in thread
From: Fabio M. De Francesco @ 2024-02-08 13:04 UTC (permalink / raw)
  To: Peter Zijlstra, Dan Williams, linux-kernel
  Cc: linux-cxl, Ingo Molnar, Dave Jiang, Jonathan Cameron, Ira Weiny,
	Fabio M. De Francesco

Add cond_guard() macro to conditional guards and use it to replace an
open-coded up_read() in show_targetN() and remove a block marked by an
'out' label.

Cc: Dave Jiang <dave.jiang@intel.com>
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Suggested-by: Dan Williams <dan.j.williams@intel.com>
Suggested-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Fabio M. De Francesco <fabio.maria.de.francesco@linux.intel.com>
---

Changes from RFC v4:
        Changed the interface of cond_guard() to take a variable to store
        a return code, the succes code and failure code, to enable a
        later check of the returned code in that variable.
Changes from RFC v5:
        Changed the interface of cond_guard() to take a statement or 
        statement-expression as its second argument to conform to Dan's 
        suggestion (thanks).
Changes from v1:
        Fixed a grammar error in the commit message of 1/2; replaced the
        name of the second argument of cond_guard() with '_fail'
        according to Jonathan's comments (thanks). 
Changes from v2:
        Changed macro's implementation to add an 'else' to protect
        against it being used incorrectly within another if() block.
        Suggested by Dan (thanks). The Reviewed-by tags on 1/2 are not
        forwarded because the implementation of cond_guard() has changed.
        Removed a redundant 'else' from show_targetN() in 2/2.
Changes from v3:
	Added braces around empty body in an 'else' statement in
	cond_guard(). Added Reviewed-by tags (Dave, Ira - thanks).

Fabio M. De Francesco (2):
  cleanup: Add cond_guard() to conditional guards
  cxl/region: Use cond_guard() in show_targetN()

 drivers/cxl/core/region.c | 16 ++++------------
 include/linux/cleanup.h   | 15 +++++++++++++++
 2 files changed, 19 insertions(+), 12 deletions(-)

-- 
2.43.0


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

* [PATCH 1/2 v4] cleanup: Add cond_guard() to conditional guards
  2024-02-08 13:04 [PATCH 0/2 v4] Add cond_guard() to conditional guards Fabio M. De Francesco
@ 2024-02-08 13:04 ` Fabio M. De Francesco
  2024-02-08 14:04   ` Jonathan Cameron
  2024-02-13 16:51   ` Fabio M. De Francesco
  2024-02-08 13:04 ` [PATCH 2/2 v4] cxl/region: Use cond_guard() in show_targetN() Fabio M. De Francesco
  1 sibling, 2 replies; 9+ messages in thread
From: Fabio M. De Francesco @ 2024-02-08 13:04 UTC (permalink / raw)
  To: Peter Zijlstra, Dan Williams, linux-kernel
  Cc: linux-cxl, Ingo Molnar, Dave Jiang, Jonathan Cameron, Ira Weiny,
	Fabio M. De Francesco

Add cond_guard() macro to conditional guards.

cond_guard() is a guard to be used with the conditional variants of locks,
like down_read_trylock() or mutex_lock_interruptible().

It takes a statement (or statement-expression) that is passed as its
second argument. That statement (or statement-expression) is executed if
waiting for a lock is interrupted or if a _trylock() fails in case of
contention.

Usage example:

	cond_guard(mutex_intr, return -EINTR, &mutex);

Consistent with other usage of _guard(), locks are unlocked at the exit of the
scope where cond_guard() is called.

Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Suggested-by: Dan Williams <dan.j.williams@intel.com>
Suggested-by: Ira Weiny <ira.weiny@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Fabio M. De Francesco <fabio.maria.de.francesco@linux.intel.com>
---
 include/linux/cleanup.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h
index c2d09bc4f976..7b54ee996414 100644
--- a/include/linux/cleanup.h
+++ b/include/linux/cleanup.h
@@ -134,6 +134,16 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \
  *	an anonymous instance of the (guard) class, not recommended for
  *	conditional locks.
  *
+ * cond_guard(name, fail, args...):
+ *	a guard to be used with the conditional variants of locks, like
+ *	down_read_trylock() or mutex_lock_interruptible. 'fail' is a
+ *	statement or statement-expression that is executed if waiting for a
+ *	lock is interrupted or if a _trylock() fails in case of contention.
+ *
+ *	Example:
+ *
+ *		cond_guard(mutex_intr, return -EINTR, &mutex);
+ *
  * scoped_guard (name, args...) { }:
  *	similar to CLASS(name, scope)(args), except the variable (with the
  *	explicit name 'scope') is declard in a for-loop such that its scope is
@@ -165,6 +175,11 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \
 
 #define __guard_ptr(_name) class_##_name##_lock_ptr
 
+#define cond_guard(_name, _fail, args...) \
+	CLASS(_name, scope)(args); \
+	if (!__guard_ptr(_name)(&scope)) _fail; \
+	else { }
+
 #define scoped_guard(_name, args...)					\
 	for (CLASS(_name, scope)(args),					\
 	     *done = NULL; __guard_ptr(_name)(&scope) && !done; done = (void *)1)
-- 
2.43.0


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

* [PATCH 2/2 v4] cxl/region: Use cond_guard() in show_targetN()
  2024-02-08 13:04 [PATCH 0/2 v4] Add cond_guard() to conditional guards Fabio M. De Francesco
  2024-02-08 13:04 ` [PATCH 1/2 v4] cleanup: " Fabio M. De Francesco
@ 2024-02-08 13:04 ` Fabio M. De Francesco
  1 sibling, 0 replies; 9+ messages in thread
From: Fabio M. De Francesco @ 2024-02-08 13:04 UTC (permalink / raw)
  To: Peter Zijlstra, Dan Williams, linux-kernel
  Cc: linux-cxl, Ingo Molnar, Dave Jiang, Jonathan Cameron, Ira Weiny,
	Fabio M. De Francesco

Use cond_guard() in show_target() to not open code an up_read() in an 'out'
block. If the down_read_interruptible() fails, the statement passed to the
second argument of cond_guard() returns -EINTR.

Cc: Peter Zijlstra <peterz@infradead.org>
Suggested-by: Dan Williams <dan.j.williams@intel.com>
Suggested-by: Ira Weiny <ira.weiny@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Fabio M. De Francesco <fabio.maria.de.francesco@linux.intel.com>
---
 drivers/cxl/core/region.c | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index ce0e2d82bb2b..704102f75c14 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -666,28 +666,20 @@ static size_t show_targetN(struct cxl_region *cxlr, char *buf, int pos)
 {
 	struct cxl_region_params *p = &cxlr->params;
 	struct cxl_endpoint_decoder *cxled;
-	int rc;
 
-	rc = down_read_interruptible(&cxl_region_rwsem);
-	if (rc)
-		return rc;
+	cond_guard(rwsem_read_intr, return -EINTR, &cxl_region_rwsem);
 
 	if (pos >= p->interleave_ways) {
 		dev_dbg(&cxlr->dev, "position %d out of range %d\n", pos,
 			p->interleave_ways);
-		rc = -ENXIO;
-		goto out;
+		return -ENXIO;
 	}
 
 	cxled = p->targets[pos];
 	if (!cxled)
-		rc = sysfs_emit(buf, "\n");
-	else
-		rc = sysfs_emit(buf, "%s\n", dev_name(&cxled->cxld.dev));
-out:
-	up_read(&cxl_region_rwsem);
+		return sysfs_emit(buf, "\n");
 
-	return rc;
+	return sysfs_emit(buf, "%s\n", dev_name(&cxled->cxld.dev));
 }
 
 static int match_free_decoder(struct device *dev, void *data)
-- 
2.43.0


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

* Re: [PATCH 1/2 v4] cleanup: Add cond_guard() to conditional guards
  2024-02-08 13:04 ` [PATCH 1/2 v4] cleanup: " Fabio M. De Francesco
@ 2024-02-08 14:04   ` Jonathan Cameron
  2024-02-08 16:21     ` Ira Weiny
  2024-02-13 16:51   ` Fabio M. De Francesco
  1 sibling, 1 reply; 9+ messages in thread
From: Jonathan Cameron @ 2024-02-08 14:04 UTC (permalink / raw)
  To: Fabio M. De Francesco
  Cc: Peter Zijlstra, Dan Williams, linux-kernel, linux-cxl,
	Ingo Molnar, Dave Jiang, Ira Weiny

On Thu,  8 Feb 2024 14:04:23 +0100
"Fabio M. De Francesco" <fabio.maria.de.francesco@linux.intel.com> wrote:

> Add cond_guard() macro to conditional guards.
> 
> cond_guard() is a guard to be used with the conditional variants of locks,
> like down_read_trylock() or mutex_lock_interruptible().
> 
> It takes a statement (or statement-expression) that is passed as its
> second argument. That statement (or statement-expression) is executed if
> waiting for a lock is interrupted or if a _trylock() fails in case of
> contention.
> 
> Usage example:
> 
> 	cond_guard(mutex_intr, return -EINTR, &mutex);
> 
> Consistent with other usage of _guard(), locks are unlocked at the exit of the
> scope where cond_guard() is called.
> 
> Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
I like the defensive else {}

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>


> Cc: Peter Zijlstra <peterz@infradead.org>
> Suggested-by: Dan Williams <dan.j.williams@intel.com>
> Suggested-by: Ira Weiny <ira.weiny@intel.com>
> Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> Reviewed-by: Ira Weiny <ira.weiny@intel.com>
> Signed-off-by: Fabio M. De Francesco <fabio.maria.de.francesco@linux.intel.com>
> ---
>  include/linux/cleanup.h | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h
> index c2d09bc4f976..7b54ee996414 100644
> --- a/include/linux/cleanup.h
> +++ b/include/linux/cleanup.h
> @@ -134,6 +134,16 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \
>   *	an anonymous instance of the (guard) class, not recommended for
>   *	conditional locks.
>   *
> + * cond_guard(name, fail, args...):
> + *	a guard to be used with the conditional variants of locks, like
> + *	down_read_trylock() or mutex_lock_interruptible. 'fail' is a
> + *	statement or statement-expression that is executed if waiting for a
> + *	lock is interrupted or if a _trylock() fails in case of contention.
> + *
> + *	Example:
> + *
> + *		cond_guard(mutex_intr, return -EINTR, &mutex);
> + *
>   * scoped_guard (name, args...) { }:
>   *	similar to CLASS(name, scope)(args), except the variable (with the
>   *	explicit name 'scope') is declard in a for-loop such that its scope is
> @@ -165,6 +175,11 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \
>  
>  #define __guard_ptr(_name) class_##_name##_lock_ptr
>  
> +#define cond_guard(_name, _fail, args...) \
> +	CLASS(_name, scope)(args); \
> +	if (!__guard_ptr(_name)(&scope)) _fail; \
> +	else { }
> +
>  #define scoped_guard(_name, args...)					\
>  	for (CLASS(_name, scope)(args),					\
>  	     *done = NULL; __guard_ptr(_name)(&scope) && !done; done = (void *)1)


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

* Re: [PATCH 1/2 v4] cleanup: Add cond_guard() to conditional guards
  2024-02-08 14:04   ` Jonathan Cameron
@ 2024-02-08 16:21     ` Ira Weiny
  0 siblings, 0 replies; 9+ messages in thread
From: Ira Weiny @ 2024-02-08 16:21 UTC (permalink / raw)
  To: Jonathan Cameron, Fabio M. De Francesco
  Cc: Peter Zijlstra, Dan Williams, linux-kernel, linux-cxl,
	Ingo Molnar, Dave Jiang, Ira Weiny

Jonathan Cameron wrote:
> On Thu,  8 Feb 2024 14:04:23 +0100
> "Fabio M. De Francesco" <fabio.maria.de.francesco@linux.intel.com> wrote:
> 
> > Add cond_guard() macro to conditional guards.
> > 
> > cond_guard() is a guard to be used with the conditional variants of locks,
> > like down_read_trylock() or mutex_lock_interruptible().
> > 
> > It takes a statement (or statement-expression) that is passed as its
> > second argument. That statement (or statement-expression) is executed if
> > waiting for a lock is interrupted or if a _trylock() fails in case of
> > contention.
> > 
> > Usage example:
> > 
> > 	cond_guard(mutex_intr, return -EINTR, &mutex);
> > 
> > Consistent with other usage of _guard(), locks are unlocked at the exit of the
> > scope where cond_guard() is called.
> > 
> > Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> I like the defensive else {}

Agreed.

Re-

Reviewed-by: Ira Weiny <ira.weiny@intel.com>

> 
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> 
> 
> > Cc: Peter Zijlstra <peterz@infradead.org>
> > Suggested-by: Dan Williams <dan.j.williams@intel.com>
> > Suggested-by: Ira Weiny <ira.weiny@intel.com>
> > Reviewed-by: Dave Jiang <dave.jiang@intel.com>
> > Reviewed-by: Ira Weiny <ira.weiny@intel.com>
> > Signed-off-by: Fabio M. De Francesco <fabio.maria.de.francesco@linux.intel.com>
> > ---
> >  include/linux/cleanup.h | 15 +++++++++++++++
> >  1 file changed, 15 insertions(+)
> > 
> > diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h
> > index c2d09bc4f976..7b54ee996414 100644
> > --- a/include/linux/cleanup.h
> > +++ b/include/linux/cleanup.h
> > @@ -134,6 +134,16 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \
> >   *	an anonymous instance of the (guard) class, not recommended for
> >   *	conditional locks.
> >   *
> > + * cond_guard(name, fail, args...):
> > + *	a guard to be used with the conditional variants of locks, like
> > + *	down_read_trylock() or mutex_lock_interruptible. 'fail' is a
> > + *	statement or statement-expression that is executed if waiting for a
> > + *	lock is interrupted or if a _trylock() fails in case of contention.
> > + *
> > + *	Example:
> > + *
> > + *		cond_guard(mutex_intr, return -EINTR, &mutex);
> > + *
> >   * scoped_guard (name, args...) { }:
> >   *	similar to CLASS(name, scope)(args), except the variable (with the
> >   *	explicit name 'scope') is declard in a for-loop such that its scope is
> > @@ -165,6 +175,11 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \
> >  
> >  #define __guard_ptr(_name) class_##_name##_lock_ptr
> >  
> > +#define cond_guard(_name, _fail, args...) \
> > +	CLASS(_name, scope)(args); \
> > +	if (!__guard_ptr(_name)(&scope)) _fail; \
> > +	else { }
> > +
> >  #define scoped_guard(_name, args...)					\
> >  	for (CLASS(_name, scope)(args),					\
> >  	     *done = NULL; __guard_ptr(_name)(&scope) && !done; done = (void *)1)
> 
> 



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

* Re: [PATCH 1/2 v4] cleanup: Add cond_guard() to conditional guards
  2024-02-08 13:04 ` [PATCH 1/2 v4] cleanup: " Fabio M. De Francesco
  2024-02-08 14:04   ` Jonathan Cameron
@ 2024-02-13 16:51   ` Fabio M. De Francesco
  2024-02-14 18:04     ` Jonathan Cameron
  1 sibling, 1 reply; 9+ messages in thread
From: Fabio M. De Francesco @ 2024-02-13 16:51 UTC (permalink / raw)
  To: Peter Zijlstra, Dan Williams, linux-kernel
  Cc: linux-cxl, Ingo Molnar, Dave Jiang, Jonathan Cameron, Ira Weiny

On Thursday, 8 February 2024 14:04:23 CET Fabio M. De Francesco wrote:
> Add cond_guard() macro to conditional guards.
> 
> cond_guard() is a guard to be used with the conditional variants of locks,
> like down_read_trylock() or mutex_lock_interruptible().
> 
> It takes a statement (or statement-expression) that is passed as its
> second argument. That statement (or statement-expression) is executed if
> waiting for a lock is interrupted or if a _trylock() fails in case of
> contention.
> 
> Usage example:
> 
> 	cond_guard(mutex_intr, return -EINTR, &mutex);
> 
> Consistent with other usage of _guard(), locks are unlocked at the exit of
> the scope where cond_guard() is called.
> 
[snip]
> 
> +#define cond_guard(_name, _fail, args...) \
> +	CLASS(_name, scope)(args); \
> +	if (!__guard_ptr(_name)(&scope)) _fail; \
> +	else { }
> +

I have converted and tested several functions in drivers/cxl and found that 
there are cases where this macro needs to be called twice in the same scope.

The current implementation fails to compile because any subsequent call to 
cond_guard() redefines "scope".

I have a solution for this, which is to instantiate a differently named 
variable each time cond_guard() is used:

#define __UNIQUE_LINE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
#define cond_guard(_name, _fail, args...) \
        CLASS(_name, __UNIQUE_LINE_ID(scope))(args); \
        if (!__guard_ptr(_name)(&__UNIQUE_LINE_ID(scope))) _fail; \
        else { }

But, before sending v5, I think it's best to wait for comments from those with 
more experience than me.

Fabio




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

* Re: [PATCH 1/2 v4] cleanup: Add cond_guard() to conditional guards
  2024-02-13 16:51   ` Fabio M. De Francesco
@ 2024-02-14 18:04     ` Jonathan Cameron
  2024-02-15 10:26       ` Jonathan Cameron
  0 siblings, 1 reply; 9+ messages in thread
From: Jonathan Cameron @ 2024-02-14 18:04 UTC (permalink / raw)
  To: Fabio M. De Francesco
  Cc: Peter Zijlstra, Dan Williams, linux-kernel, linux-cxl,
	Ingo Molnar, Dave Jiang, Ira Weiny

On Tue, 13 Feb 2024 17:51:26 +0100
"Fabio M. De Francesco" <fabio.maria.de.francesco@linux.intel.com> wrote:

> On Thursday, 8 February 2024 14:04:23 CET Fabio M. De Francesco wrote:
> > Add cond_guard() macro to conditional guards.
> > 
> > cond_guard() is a guard to be used with the conditional variants of locks,
> > like down_read_trylock() or mutex_lock_interruptible().
> > 
> > It takes a statement (or statement-expression) that is passed as its
> > second argument. That statement (or statement-expression) is executed if
> > waiting for a lock is interrupted or if a _trylock() fails in case of
> > contention.
> > 
> > Usage example:
> > 
> > 	cond_guard(mutex_intr, return -EINTR, &mutex);
> > 
> > Consistent with other usage of _guard(), locks are unlocked at the exit of
> > the scope where cond_guard() is called.
> >   
> [snip]
> > 
> > +#define cond_guard(_name, _fail, args...) \
> > +	CLASS(_name, scope)(args); \
> > +	if (!__guard_ptr(_name)(&scope)) _fail; \
> > +	else { }
> > +  
> 
> I have converted and tested several functions in drivers/cxl and found that 
> there are cases where this macro needs to be called twice in the same scope.
> 
> The current implementation fails to compile because any subsequent call to 
> cond_guard() redefines "scope".
> 
> I have a solution for this, which is to instantiate a differently named 
> variable each time cond_guard() is used:
> 
> #define __UNIQUE_LINE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
> #define cond_guard(_name, _fail, args...) \
>         CLASS(_name, __UNIQUE_LINE_ID(scope))(args); \
>         if (!__guard_ptr(_name)(&__UNIQUE_LINE_ID(scope))) _fail; \
>         else { }
> 
> But, before sending v5, I think it's best to wait for comments from those with 
> more experience than me.

Ah. So you can't use __UNIQUE_ID as guard does because we need it to be stable
across the two uses.  What you have looks fine to me.
We might end up with someone putting multiple calls in a macro but in my
view anyone doing that level of complexity in a macro is shooting themselves
in the foot.

Jonathan


> 
> Fabio
> 
> 
> 
> 


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

* Re: [PATCH 1/2 v4] cleanup: Add cond_guard() to conditional guards
  2024-02-14 18:04     ` Jonathan Cameron
@ 2024-02-15 10:26       ` Jonathan Cameron
  2024-02-15 13:12         ` Fabio M. De Francesco
  0 siblings, 1 reply; 9+ messages in thread
From: Jonathan Cameron @ 2024-02-15 10:26 UTC (permalink / raw)
  To: Fabio M. De Francesco
  Cc: Peter Zijlstra, Dan Williams, linux-kernel, linux-cxl,
	Ingo Molnar, Dave Jiang, Ira Weiny

On Wed, 14 Feb 2024 18:04:52 +0000
Jonathan Cameron <Jonathan.Cameron@Huawei.com> wrote:

> On Tue, 13 Feb 2024 17:51:26 +0100
> "Fabio M. De Francesco" <fabio.maria.de.francesco@linux.intel.com> wrote:
> 
> > On Thursday, 8 February 2024 14:04:23 CET Fabio M. De Francesco wrote:  
> > > Add cond_guard() macro to conditional guards.
> > > 
> > > cond_guard() is a guard to be used with the conditional variants of locks,
> > > like down_read_trylock() or mutex_lock_interruptible().
> > > 
> > > It takes a statement (or statement-expression) that is passed as its
> > > second argument. That statement (or statement-expression) is executed if
> > > waiting for a lock is interrupted or if a _trylock() fails in case of
> > > contention.
> > > 
> > > Usage example:
> > > 
> > > 	cond_guard(mutex_intr, return -EINTR, &mutex);
> > > 
> > > Consistent with other usage of _guard(), locks are unlocked at the exit of
> > > the scope where cond_guard() is called.
> > >     
> > [snip]  
> > > 
> > > +#define cond_guard(_name, _fail, args...) \
> > > +	CLASS(_name, scope)(args); \
> > > +	if (!__guard_ptr(_name)(&scope)) _fail; \
> > > +	else { }
> > > +    
> > 
> > I have converted and tested several functions in drivers/cxl and found that 
> > there are cases where this macro needs to be called twice in the same scope.
> > 
> > The current implementation fails to compile because any subsequent call to 
> > cond_guard() redefines "scope".
> > 
> > I have a solution for this, which is to instantiate a differently named 
> > variable each time cond_guard() is used:
> > 
> > #define __UNIQUE_LINE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
> > #define cond_guard(_name, _fail, args...) \
> >         CLASS(_name, __UNIQUE_LINE_ID(scope))(args); \
> >         if (!__guard_ptr(_name)(&__UNIQUE_LINE_ID(scope))) _fail; \
> >         else { }
> > 
> > But, before sending v5, I think it's best to wait for comments from those with 
> > more experience than me.  
> 
> Ah. So you can't use __UNIQUE_ID as guard does because we need it to be stable
> across the two uses.  What you have looks fine to me.
> We might end up with someone putting multiple calls in a macro but in my
> view anyone doing that level of complexity in a macro is shooting themselves
> in the foot.

Thought more on this whilst cycling home.  Can you use another level
of macros in combination with __UNIQUE_ID that guard uses?
My skills with macros are very limited so I'm sure I got something wrong,
but along the lines of.

#define __cond_class(__unique, _name, _fail, args...) \
   CLASS(_name, __unique)(args); \
         if (!__guard_ptr(_name)(&__unique)) _fail; \
         else { }
#define cond_class(_name, _fail, args... ) \
    __cond_class(__UNIQUE_ID(guard), _name, _fail, args...

?

> 
> Jonathan
> 
> 
> > 
> > Fabio
> > 
> > 
> > 
> >   
> 
> 


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

* Re: [PATCH 1/2 v4] cleanup: Add cond_guard() to conditional guards
  2024-02-15 10:26       ` Jonathan Cameron
@ 2024-02-15 13:12         ` Fabio M. De Francesco
  0 siblings, 0 replies; 9+ messages in thread
From: Fabio M. De Francesco @ 2024-02-15 13:12 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Peter Zijlstra, Dan Williams, linux-kernel, linux-cxl,
	Ingo Molnar, Dave Jiang, Ira Weiny

On Thursday, 15 February 2024 11:26:42 CET Jonathan Cameron wrote:
> On Wed, 14 Feb 2024 18:04:52 +0000
> 
> Jonathan Cameron <Jonathan.Cameron@Huawei.com> wrote:
> > On Tue, 13 Feb 2024 17:51:26 +0100
> > 
> > "Fabio M. De Francesco" <fabio.maria.de.francesco@linux.intel.com> wrote:
> > > On Thursday, 8 February 2024 14:04:23 CET Fabio M. De Francesco wrote:
> > > > Add cond_guard() macro to conditional guards.
> > > > 
> > > > cond_guard() is a guard to be used with the conditional variants of
> > > > locks,
> > > > like down_read_trylock() or mutex_lock_interruptible().
> > > > 
> > > > It takes a statement (or statement-expression) that is passed as its
> > > > second argument. That statement (or statement-expression) is executed
> > > > if
> > > > waiting for a lock is interrupted or if a _trylock() fails in case of
> > > > contention.
> > > > 
> > > > Usage example:
> > > > 	cond_guard(mutex_intr, return -EINTR, &mutex);
> > > > 
> > > > Consistent with other usage of _guard(), locks are unlocked at the
> > > > exit of
> > > > the scope where cond_guard() is called.
> > > 
> > > [snip]
> > > 
> > > > +#define cond_guard(_name, _fail, args...) \
> > > > +	CLASS(_name, scope)(args); \
> > > > +	if (!__guard_ptr(_name)(&scope)) _fail; \
> > > > +	else { }
> > > > +
> > > 
> > > I have converted and tested several functions in drivers/cxl and found
> > > that
> > > there are cases where this macro needs to be called twice in the same
> > > scope.
> > > 
> > > The current implementation fails to compile because any subsequent call
> > > to
> > > cond_guard() redefines "scope".
> > > 
> > > I have a solution for this, which is to instantiate a differently named
> > > variable each time cond_guard() is used:
> > > 
> > > #define __UNIQUE_LINE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix),
> > > __LINE__) #define cond_guard(_name, _fail, args...) \
> > > 
> > >         CLASS(_name, __UNIQUE_LINE_ID(scope))(args); \
> > >         if (!__guard_ptr(_name)(&__UNIQUE_LINE_ID(scope))) _fail; \
> > >         else { }
> > > 
> > > But, before sending v5, I think it's best to wait for comments from
> > > those with more experience than me.
> > 
> > Ah. So you can't use __UNIQUE_ID as guard does because we need it to be
> > stable across the two uses.  What you have looks fine to me.
> > We might end up with someone putting multiple calls in a macro but in my
> > view anyone doing that level of complexity in a macro is shooting
> > themselves in the foot.
> 
> Thought more on this whilst cycling home.  Can you use another level
> of macros in combination with __UNIQUE_ID that guard uses?
> My skills with macros are very limited so I'm sure I got something wrong,
> but along the lines of.
> 
> #define __cond_class(__unique, _name, _fail, args...) \
>    CLASS(_name, __unique)(args); \
>          if (!__guard_ptr(_name)(&__unique)) _fail; \
>          else { }
> #define cond_class(_name, _fail, args... ) \
>     __cond_class(__UNIQUE_ID(guard), _name, _fail, args...
> 
> ?
>
Yes, certainly.

Your solution is more elegant. We can reuse __UNIQUE_ID(). There is no need of 
a new helper macro. Thanks.

But with s/cond_class/cond_guard/ and s/guard/scope/ (I think that "scope" 
makes the purpose of that variable clearer).  

I think I'll wait a bit more in case someone else wants to comment and then 
I'll submit v5.

Fabio
> 
> > Jonathan
> > 
> > > Fabio




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

end of thread, other threads:[~2024-02-15 13:12 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-08 13:04 [PATCH 0/2 v4] Add cond_guard() to conditional guards Fabio M. De Francesco
2024-02-08 13:04 ` [PATCH 1/2 v4] cleanup: " Fabio M. De Francesco
2024-02-08 14:04   ` Jonathan Cameron
2024-02-08 16:21     ` Ira Weiny
2024-02-13 16:51   ` Fabio M. De Francesco
2024-02-14 18:04     ` Jonathan Cameron
2024-02-15 10:26       ` Jonathan Cameron
2024-02-15 13:12         ` Fabio M. De Francesco
2024-02-08 13:04 ` [PATCH 2/2 v4] cxl/region: Use cond_guard() in show_targetN() Fabio M. De Francesco

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.