[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250219163211.GC11480@pendragon.ideasonboard.com>
Date: Wed, 19 Feb 2025 18:32:11 +0200
From: Laurent Pinchart <laurent.pinchart@...asonboard.com>
To: Willy Tarreau <w@....eu>
Cc: James Bottomley <James.Bottomley@...senPartnership.com>,
"Martin K. Petersen" <martin.petersen@...cle.com>,
Dan Carpenter <dan.carpenter@...aro.org>,
Christoph Hellwig <hch@...radead.org>,
Miguel Ojeda <miguel.ojeda.sandonis@...il.com>,
rust-for-linux <rust-for-linux@...r.kernel.org>,
Linus Torvalds <torvalds@...ux-foundation.org>,
Greg KH <gregkh@...uxfoundation.org>,
David Airlie <airlied@...il.com>, linux-kernel@...r.kernel.org,
ksummit@...ts.linux.dev
Subject: Re: Rust kernel policy
On Wed, Feb 19, 2025 at 05:15:43PM +0100, Willy Tarreau wrote:
> On Wed, Feb 19, 2025 at 06:07:23PM +0200, Laurent Pinchart wrote:
>
> > > Regardless I do understand how these cleanups can help in a number of
> > > case, at least to avoid some code duplication.
> >
> > They're particularly useful to "destroy" local variables that don't need
> > to be returned. This allows implementing scope guards, to facilitate
> > lock handling for instance. Once a mutex guard is instantiated, the
> > mutex is locked, and it will be guaranteed to be unlocked in every
> > return path.
>
> Yeah absolutely. However I remember having faced code in the past where
> developers had abused this "unlock on return" concept resulting in locks
> lazily being kept way too long after an operation. I don't think this
> will happen in the kernel thanks to reviews, but typically all the stuff
> that's done after a locked retrieval was done normally is down outside
> of the lock, while here for the sake of not dealing with unlocks, quite
> a few lines were still covered by the lock for no purpose. Anyway
> there's no perfect solution.
There actually is in this case :-) You can reduce the scope with scoped
guards:
static int gpio_mockup_get_multiple(struct gpio_chip *gc,
unsigned long *mask, unsigned long *bits)
{
struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
unsigned int bit, val;
scoped_guard(mutex, &chip->lock) {
for_each_set_bit(bit, mask, gc->ngpio) {
val = __gpio_mockup_get(chip, bit);
__assign_bit(bit, bits, val);
}
}
return 0;
}
which is equivalent to
static int gpio_mockup_get_multiple(struct gpio_chip *gc,
unsigned long *mask, unsigned long *bits)
{
struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
unsigned int bit, val;
{
guard(mutex)(&chip->lock);
for_each_set_bit(bit, mask, gc->ngpio) {
val = __gpio_mockup_get(chip, bit);
__assign_bit(bit, bits, val);
}
}
return 0;
}
In this particular example there's nothing being done after the scope,
but you could have more code there.
> Ideally when a compiler is smart enough to say "I would have cleaned
> up here", it could be cool to just have a warning so that the developer
> decides where to perform it. The problem is that it'd quickly becomes
> a mess since the compiler cannot guess that you've done your own cleanup
> before (without yet other anotations), which precisely is the point of
> doing it unconditionally when leaving scope.
--
Regards,
Laurent Pinchart
Powered by blists - more mailing lists