public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: David Sterba <dsterba@suse.cz>
To: Gladyshev Ilya <foxido@foxido.dev>
Cc: David Sterba <dsterba@suse.com>,
	neelx@suse.com, linux-btrfs@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH 4/8] btrfs: simplify function protections with guards
Date: Thu, 13 Nov 2025 12:25:14 +0100	[thread overview]
Message-ID: <20251113112514.GN13846@suse.cz> (raw)
In-Reply-To: <35e1977e-7cca-4ea3-9df8-0a2b43bc0f85@foxido.dev>

On Thu, Nov 13, 2025 at 01:06:42PM +0300, Gladyshev Ilya wrote:
> On 11/13/25 11:43, David Sterba wrote:
> > On Wed, Nov 12, 2025 at 09:49:40PM +0300, Gladyshev Ilya wrote:
> >> Replaces cases like
> >>
> >> void foo() {
> >>      spin_lock(&lock);
> >>      ... some code ...
> >>      spin_unlock(&lock)
> >> }
> >>
> >> with
> >>
> >> void foo() {
> >>      guard(spinlock)(&lock);
> >>      ... some code ...
> >> }
> >>
> >> While it doesn't has any measurable impact,
> > 
> > There is impact, as Daniel mentioned elsewhere, this also adds the
> > variable on stack. It's measuable on the stack meter, one variable is
> > "nothing" but combined wherever the guards are used can add up. We don't
> > mind adding variables where needed, occasional cleanups and stack
> > reduction is done. Here it's a systematic stack use increase, not a
> > reason to reject the guards but still something I cannot just brush off
> I thought it would be optimized out by the compiler in the end, I will 
> probably recheck this

There are cases where compiler will optimize it out, IIRC when the lock
is embedded in a structure, and not when the pointer is dereferenced.

> >> it makes clear that whole
> >> function body is protected under lock and removes future errors with
> >> additional cleanup paths.
> > 
> > The pattern above is the one I find problematic the most, namely in
> > longer functions or evolved code. Using your example as starting point
> > a followup change adds code outside of the locked section:
> > 
> > void foo() {
> >      spin_lock(&lock);
> >      ... some code ...
> >      spin_unlock(&lock)
> > 
> >      new code;
> > }
> > 
> > with
> > 
> > void foo() {
> >      guard(spinlock)(&lock);
> >      ... some code ...
> > 
> >      new code;
> > }
> > 
> > This will lead to longer critical sections or even incorrect code
> > regarding locking when new code must not run under lock.
> > 
> > The fix is to convert it to scoped locking, with indentation and code
> > churn to unrelated code to the new one.
> > 
> > Suggestions like refactoring to make minimal helpers and functions is
> > another unecessary churn and breaks code reading flow.
> 
> What if something like C++ unique_lock existed? So code like this would 
> be possible:
> 
> void foo() {
>    GUARD = unique_lock(&spin);
> 
>    if (a)
>      // No unlocking required -> it will be done automatically
>      return;
> 
>    unlock(GUARD);
> 
>    ... unlocked code ...
> 
>    // Guard undestands that it's unlocked and does nothing
>    return;
> }
> 
> It has similar semantics to scoped_guard [however it has weaker 
> protection -- goto from locked section can bypass `unlock` and hold lock 
> until return], but it doesn't introduce diff noise correlated with 
> indentations.
> 
> Another approach is allowing scoped_guards to have different indentation 
> codestyle to avoid indentation of internal block [like goto labels for 
> example].
> 
> However both of this approaches has their own downsides and are pure 
> proposals

Thanks, it's good to have concrete examples to discuss. It feels like
we'd switch away from C and force patterns that are maybe common in
other languages like C++ that do things under the hood and it's fine
there as it's the mental programming model one has. This feels alien to
kernel C programming, namely for locking where the "hide things" is IMO
worse than "make things explicit".

There are cases where switching to guards would be reasonable because
the functions are short and simple but then it does not utilize the
semantics of automatic cleanup. In more complex functions it would mean
to make more structural changes to the code at the cost of churn and
merge conflicts of backported patches.

  reply	other threads:[~2025-11-13 11:25 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-12 18:49 [RFC PATCH 0/8] use cleanup.h in btrfs Gladyshev Ilya
2025-11-12 18:49 ` [RFC PATCH 1/8] btrfs: remove redundant label in __del_qgroup_relation Gladyshev Ilya
2025-11-12 18:49 ` [RFC PATCH 2/8] btrfs: move kfree out of btrfs_create_qgroup's cleanup path Gladyshev Ilya
2025-11-12 20:30   ` Qu Wenruo
2025-11-12 18:49 ` [RFC PATCH 3/8] btrfs: simplify control flow in scrub_simple_mirror Gladyshev Ilya
2025-11-12 18:49 ` [RFC PATCH 4/8] btrfs: simplify function protections with guards Gladyshev Ilya
2025-11-13  8:43   ` David Sterba
2025-11-13 10:06     ` Gladyshev Ilya
2025-11-13 11:25       ` David Sterba [this message]
2025-11-13 12:30         ` Daniel Vacek
2025-11-12 18:49 ` [RFC PATCH 5/8] btrfs: use cleanup.h guard()s to simplify unlocks on return Gladyshev Ilya
2025-11-12 18:49 ` [RFC PATCH 6/8] btrfs: simplify cleanup via scoped_guard() Gladyshev Ilya
2025-11-13  8:48   ` David Sterba
2025-11-12 18:49 ` [RFC PATCH 7/8] btrfs: simplify return path via cleanup.h Gladyshev Ilya
2025-11-12 20:50   ` Qu Wenruo
2025-11-13  8:54     ` David Sterba
2025-11-13 12:48       ` Daniel Vacek
2025-11-12 18:49 ` [RFC PATCH 8/8] btrfs: simplify cleanup in btrfs_add_qgroup_relation Gladyshev Ilya
2025-11-12 20:46   ` Qu Wenruo
2025-11-12 20:55 ` [RFC PATCH 0/8] use cleanup.h in btrfs Qu Wenruo
2025-11-13  8:01   ` Gladyshev Ilya

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=20251113112514.GN13846@suse.cz \
    --to=dsterba@suse.cz \
    --cc=dsterba@suse.com \
    --cc=foxido@foxido.dev \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=neelx@suse.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox