From: "Fabio M. De Francesco" <fabio.maria.de.francesco@linux.intel.com>
To: linux-kernel@vger.kernel.org, Dan Williams <dan.j.williams@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
Dan Williams <dan.j.williams@intel.com>,
Ira Weiny <ira.weiny@intel.com>
Subject: Re: [RFC PATCH v2] cleanup: Add cond_guard() to conditional guards
Date: Tue, 30 Jan 2024 18:33:54 +0100 [thread overview]
Message-ID: <22169722.EfDdHjke4D@fdefranc-mobl3> (raw)
In-Reply-To: <65b92b91a41a8_5cc6f29484@dwillia2-mobl3.amr.corp.intel.com.notmuch>
On Tuesday, 30 January 2024 18:02:09 CET Dan Williams wrote:
> Fabio M. De Francesco wrote:
> > Add cond_guard() to conditional guards.
> >
> > cond_guard() is used for the _interruptible(), _killable(), and _try
> > versions of locks. It expects a block where the failure can be handled
> > (e.g., calling printk() and returning -EINTR in case of failure).
> >
> > As the other guards, it avoids to open code the release of the lock
> > after a goto to an 'out' label.
> >
> > This remains an RFC because Dan suggested a slightly different syntax:
> > if (cond_guard(...))
> >
> > return -EINTR;
> >
> > But the scoped_cond_guard() macro omits the if statement:
> > scoped_cond_guard (...) {
> > }
> >
> > Thus define cond_guard() similarly to scoped_cond_guard() but with a block
> >
> > to handle the failure case:
> > cond_guard(...)
> >
> > return -EINTR;
>
> That's too subtle for me, because of the mistakes that can be made with
> brackets how about a syntax like:
>
> cond_guard(..., return -EINTR, ...)
>
> ...to make it clear what happens if the lock acquisition fails without
> having to remember there is a hidden incomplete "if ()" statement in
> that macro? More below...
As you propose I can't see how to handle multi-line error path like in:
cond_guard(...) {
dev_dbg(...);
return -EINTR;
}
I added a similar example in a comment in cleanup.h.
>
> > Cc: Peter Zijlstra <peterz@infradead.org>
> > Cc: 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> ---
> >
> > drivers/cxl/core/region.c | 17 +++++------------
> > include/linux/cleanup.h | 13 +++++++++++++
> > 2 files changed, 18 insertions(+), 12 deletions(-)
> >
> > [...]
> >
> > diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h
> > index c2d09bc4f976..fc850e61a47e 100644
> > --- a/include/linux/cleanup.h
> > +++ b/include/linux/cleanup.h
> > @@ -134,6 +134,15 @@ 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, args...):
> > + * for conditional locks like mutex_trylock() or
> > down_read_interruptible(). + * It expects a block for handling
errors
> > like in the following example: + *
> > + * cond_guard(rwsem_read_intr, &my_sem) {
> > + * printk(KERN_NOTICE "Try failure in work0()\n");
> > + * return -EINTR;
> > + * }
> > + *
> >
> > * 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 +174,10 @@ static inline class_##_name##_t
> > class_##_name##ext##_constructor(_init_args) \>
> > #define __guard_ptr(_name) class_##_name##_lock_ptr
> >
> > +#define cond_guard(_name, args...) \
> > + CLASS(_name, scope)(args); \
> > + if (!__guard_ptr(_name)(&scope))
>
> This needs to protect against being used within another if () block.
> Imagine a case of:
>
> if (...) {
> cond_guard(...);
> <statement>
> } else if (...)
>
> ...does that "else if" belong to the first "if ()" or the hidden one
> inside the macro?
Good question.
> You can steal the embedded "if ()" trick from scoped_cond_guard() and do
> something like (untested):
>
> #define cond_guard(_name, _fail, args...) \
> CLASS(_name, scope)(args); \
> if (!__guard_ptr(_name)(&scope)) _fail; else /* pass */;
I think this may work, but...
Again, with this interface there is no means to handle multi-line error paths.
I wanted an interface sufficiently flexible to handle logging + return -EINTR,
and possibly more lines to undo something.
Can we have two macros, this for multi-line error paths, and one other, like
you suggested, for an immediate 'return -EINTR'?
Thanks,
Fabio
next prev parent reply other threads:[~2024-01-30 17:34 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-30 16:38 [RFC PATCH v2] cleanup: Add cond_guard() to conditional guards Fabio M. De Francesco
2024-01-30 17:02 ` Dan Williams
2024-01-30 17:33 ` Fabio M. De Francesco [this message]
2024-01-30 17:58 ` Dan Williams
2024-01-31 13:11 ` Fabio M. De Francesco
2024-01-30 17:55 ` Fabio M. De Francesco
2024-01-30 18:43 ` Ira Weiny
2024-01-30 19:06 ` Dan Williams
2024-01-31 0:04 ` Ira Weiny
2024-01-31 0:43 ` 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=22169722.EfDdHjke4D@fdefranc-mobl3 \
--to=fabio.maria.de.francesco@linux.intel.com \
--cc=dan.j.williams@intel.com \
--cc=ira.weiny@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=peterz@infradead.org \
/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.