Re: Rust kernel policy

Laurent Pinchart
2025-02-19T16:32:35Z

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