Message ID | 20240402164345.14065-1-hdegoede@redhat.com |
---|---|
State | New |
Headers | show |
Series | [v2] gpiolib: Fix triggering "kobject: 'gpiochipX' is not initialized, yet" kobject_get() errors | expand |
On Tue, Apr 2, 2024 at 7:43 PM Hans de Goede <hdegoede@redhat.com> wrote: > > When a gpiochip gets added by loading a module, then another driver may > be waiting for that gpiochip to load on the deferred-probe list. > > If the deferred-probe for the consumer of gpiochip then triggers between > the gpiodev_add_to_list_unlocked() calls which makes gpio_device_find() > see the chip and the gpiochip_setup_dev() later then gpio_device_find() > does a kobject_get() on an uninitialzed kobject since the kobject is uninitialized > initialized by gpiochip_setup_dev() calling device_initialize(): > > arizona spi-10WM5102:00: cannot find GPIO chip arizona, deferring > arizona spi-10WM5102:00: cannot find GPIO chip arizona, deferring > ------------[ cut here ]------------ > kobject: 'gpiochip5' (00000000241466f2): is not initialized, yet kobject_get() is being called. > WARNING: CPU: 3 PID: 42 at lib/kobject.c:640 kobject_get+0x43/0x70 > Call Trace: > kobject_get > gpio_device_find > gpiod_find_and_request > gpiod_get > snd_byt_wm5102_mc_probe > > Not only is the device not initialized yet, but when the gpio-device is > added to the list things like the irqchip also have not been initialized > yet. > > So gpio_device_find() should really ignore the gpio-device until > gpiochip_add_data_with_key() is fully done. Add a device_is_registered() > check to gpio_device_find() to ignore gpio-devices on the list which are > not yet fully initialized. Reviewed-by: Andy Shevchenko <andy@kernel.org>
Hi, On 4/2/24 6:51 PM, Andy Shevchenko wrote: > On Tue, Apr 2, 2024 at 7:43 PM Hans de Goede <hdegoede@redhat.com> wrote: >> >> When a gpiochip gets added by loading a module, then another driver may >> be waiting for that gpiochip to load on the deferred-probe list. >> >> If the deferred-probe for the consumer of gpiochip then triggers between >> the gpiodev_add_to_list_unlocked() calls which makes gpio_device_find() >> see the chip and the gpiochip_setup_dev() later then gpio_device_find() >> does a kobject_get() on an uninitialzed kobject since the kobject is > > uninitialized Bartosz, can you fix this up while merging or do you prefer a v3? >> initialized by gpiochip_setup_dev() calling device_initialize(): >> >> arizona spi-10WM5102:00: cannot find GPIO chip arizona, deferring >> arizona spi-10WM5102:00: cannot find GPIO chip arizona, deferring >> ------------[ cut here ]------------ >> kobject: 'gpiochip5' (00000000241466f2): is not initialized, yet kobject_get() is being called. >> WARNING: CPU: 3 PID: 42 at lib/kobject.c:640 kobject_get+0x43/0x70 >> Call Trace: >> kobject_get >> gpio_device_find >> gpiod_find_and_request >> gpiod_get >> snd_byt_wm5102_mc_probe >> >> Not only is the device not initialized yet, but when the gpio-device is >> added to the list things like the irqchip also have not been initialized >> yet. >> >> So gpio_device_find() should really ignore the gpio-device until >> gpiochip_add_data_with_key() is fully done. Add a device_is_registered() >> check to gpio_device_find() to ignore gpio-devices on the list which are >> not yet fully initialized. > > Reviewed-by: Andy Shevchenko <andy@kernel.org> Thank you for the review. Regards, Hans
On Wed, Apr 3, 2024 at 10:17 AM Hans de Goede <hdegoede@redhat.com> wrote: > > Hi, > > On 4/2/24 6:51 PM, Andy Shevchenko wrote: > > On Tue, Apr 2, 2024 at 7:43 PM Hans de Goede <hdegoede@redhat.com> wrote: > >> > >> When a gpiochip gets added by loading a module, then another driver may > >> be waiting for that gpiochip to load on the deferred-probe list. > >> > >> If the deferred-probe for the consumer of gpiochip then triggers between > >> the gpiodev_add_to_list_unlocked() calls which makes gpio_device_find() > >> see the chip and the gpiochip_setup_dev() later then gpio_device_find() > >> does a kobject_get() on an uninitialzed kobject since the kobject is > > > > uninitialized > > Bartosz, can you fix this up while merging or do you prefer a v3? > Yes, queued for fixes. Bart
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 59ccf9a3e153..94903fc1c145 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1175,6 +1175,9 @@ struct gpio_device *gpio_device_find(const void *data, list_for_each_entry_srcu(gdev, &gpio_devices, list, srcu_read_lock_held(&gpio_devices_srcu)) { + if (!device_is_registered(&gdev->dev)) + continue; + guard(srcu)(&gdev->srcu); gc = srcu_dereference(gdev->chip, &gdev->srcu);
When a gpiochip gets added by loading a module, then another driver may be waiting for that gpiochip to load on the deferred-probe list. If the deferred-probe for the consumer of gpiochip then triggers between the gpiodev_add_to_list_unlocked() calls which makes gpio_device_find() see the chip and the gpiochip_setup_dev() later then gpio_device_find() does a kobject_get() on an uninitialzed kobject since the kobject is initialized by gpiochip_setup_dev() calling device_initialize(): arizona spi-10WM5102:00: cannot find GPIO chip arizona, deferring arizona spi-10WM5102:00: cannot find GPIO chip arizona, deferring ------------[ cut here ]------------ kobject: 'gpiochip5' (00000000241466f2): is not initialized, yet kobject_get() is being called. WARNING: CPU: 3 PID: 42 at lib/kobject.c:640 kobject_get+0x43/0x70 Call Trace: kobject_get gpio_device_find gpiod_find_and_request gpiod_get snd_byt_wm5102_mc_probe Not only is the device not initialized yet, but when the gpio-device is added to the list things like the irqchip also have not been initialized yet. So gpio_device_find() should really ignore the gpio-device until gpiochip_add_data_with_key() is fully done. Add a device_is_registered() check to gpio_device_find() to ignore gpio-devices on the list which are not yet fully initialized. Fixes: aab5c6f20023 ("gpio: set device type for GPIO chips") Suggested-by: Bartosz Golaszewski <brgl@bgdev.pl> Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- Changes in v2: -Move device_is_registered() outside of RCU read lock section -Simplify backtrace in commit msg -Add fixes tag --- drivers/gpio/gpiolib.c | 3 +++ 1 file changed, 3 insertions(+)