Re: [PATCH v2 1/2] gpio: shared-proxy: always serialize with a sleeping mutex
Bartosz Golaszewski <[email protected]>
| Newsgroups | org.infradead.lists.linux-amlogic,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-gpio,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAMRc=MfpXEFreGynUtAJfvW+27OgKiTOEZvkddt5U0+QG4cYeQ@mail.gmail.com> |
On Thu, 25 Jun 2026 13:57:17 +0200, Viacheslav Bocharov <[email protected]> said: > The shared GPIO descriptor used either a mutex or a spinlock, chosen at > runtime from the underlying chip's can_sleep: > > shared_desc->can_sleep = gpiod_cansleep(shared_desc->desc); > ... if (can_sleep) mutex_lock(); else spin_lock_irqsave(); > > can_sleep describes only the value path (->get/->set). Under the same > lock, however, the proxy may call gpiod_set_config() and > gpiod_direction_*(), which can reach pinctrl paths that take a mutex > (e.g. gpiod_set_config() -> gpiochip_generic_config() -> > pinctrl_gpio_set_config()), independent of can_sleep. On a controller > with non-sleeping MMIO value ops the descriptor lock was a spinlock, so > the sleeping pinctrl call ran from atomic context. Reproduced on an > Amlogic A113X board with the workaround from commit 28f240683871 > ("pinctrl: meson: mark the GPIO controller as sleeping") reverted; the > original Khadas VIM3 report hit the same path: > > BUG: sleeping function called from invalid context > __mutex_lock > pinctrl_get_device_gpio_range > pinctrl_gpio_set_config > gpiochip_generic_config > gpiod_set_config > gpio_shared_proxy_set_config <- voting spinlock held > ... > mmc_pwrseq_simple_probe > > The spinlock existed to take the value vote from atomic context, but the > vote and the (possibly sleeping) control operations share the same state > and lock, so this scheme cannot serialize config under a mutex and still > offer atomic value access. Always serialize the shared descriptor with a > mutex instead and mark the proxy a sleeping gpiochip, driving the > underlying GPIO through the cansleep value accessors: those are valid > for both sleeping and non-sleeping chips, so value access keeps working > on fast controllers, at the cost of no longer being atomic. > > This is observable: consumers gating on gpiod_cansleep() take their > sleeping branch on a proxied GPIO (mmc-pwrseq-emmc skips its > emergency-restart reset handler; its normal reset is unaffected), and > consumers that reject sleeping GPIOs (pwm-gpio, ps2-gpio, ...) would > fail to probe. Such atomic users do not share a pin through the proxy, > whose purpose is voting on shared reset/enable lines. The same narrowing > already applies on Amlogic since that workaround, and rockchip > addressed the identical splat per-driver in commit 7ca497be0016 ("gpio: > rockchip: Stop calling pinctrl for set_direction"); fixing the proxy > addresses the locking error once, for every controller. > > The lock type was added by commit a060b8c511ab ("gpiolib: implement > low-level, shared GPIO support"); the sleeping call under it arrived with > the proxy driver. > > Fixes: e992d54c6f97 ("gpio: shared-proxy: implement the shared GPIO proxy driver") > Reported-by: Marek Szyprowski <[email protected]> > Closes: https://lore.kernel.org/all/[email protected]/ > Signed-off-by: Viacheslav Bocharov <[email protected]> > --- This looks good to me. Linus: do you want me to take patch 2/2 as well? I'll send it for v7.2-rc2. Bart _______________________________________________ linux-amlogic mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-amlogic