Message ID | 20240213093108.13922-2-brgl@bgdev.pl |
---|---|
State | New |
Headers | show |
Series | gpio: fix SRCU bugs | expand |
On Tue, Feb 13, 2024 at 10:31 AM Bartosz Golaszewski <brgl@bgdev.pl> wrote: > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > gpiod_hog() may be called without the gpio_device SRCU read lock taken > so we need to do it here as well. It's alright if someone else is > already holding the lock as SRCU read critical sections can be nested. > > Fixes: d83cee3d2bb1 ("gpio: protect the pointer to gpio_chip in gpio_device with SRCU") > Reported-by: kernel test robot <oliver.sang@intel.com> > Closes: https://lore.kernel.org/oe-lkp/202402122234.d85cca9b-lkp@intel.com > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Looking at the CLASS() stuff I see this is definitely the way to go with the code now that we face massive scaling. Nice work. Yours, Linus Walleij
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 82811d9a4477..c1391a9a0af6 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -4492,24 +4492,27 @@ EXPORT_SYMBOL_GPL(gpiod_get_index_optional); int gpiod_hog(struct gpio_desc *desc, const char *name, unsigned long lflags, enum gpiod_flags dflags) { - struct gpio_chip *gc; + struct gpio_device *gdev = desc->gdev; struct gpio_desc *local_desc; int hwnum; int ret; + CLASS(gpio_chip_guard, guard)(desc); + if (!guard.gc) + return -ENODEV; + if (test_and_set_bit(FLAG_IS_HOGGED, &desc->flags)) return 0; - gc = gpiod_to_chip(desc); hwnum = gpio_chip_hwgpio(desc); - local_desc = gpiochip_request_own_desc(gc, hwnum, name, + local_desc = gpiochip_request_own_desc(guard.gc, hwnum, name, lflags, dflags); if (IS_ERR(local_desc)) { clear_bit(FLAG_IS_HOGGED, &desc->flags); ret = PTR_ERR(local_desc); pr_err("requesting hog GPIO %s (chip %s, offset %d) failed, %d\n", - name, gc->label, hwnum, ret); + name, gdev->label, hwnum, ret); return ret; }