śr., 18 gru 2019 o 14:26 Jia-Ju Bai <baijiaju1990@xxxxxxxxx> napisał(a): > > The driver may sleep while holding a spinlock. > The function call path (from bottom to top) in Linux 4.19 is: > > drivers/gpio/gpiolib-sysfs.c, 796: > mutex_lock in gpiochip_sysfs_unregister > drivers/gpio/gpiolib.c, 1455: > gpiochip_sysfs_unregister in gpiochip_remove > drivers/gpio/gpio-grgpio.c, 460: > gpiochip_remove in grgpio_remove > drivers/gpio/gpio-grgpio.c, 449: > _raw_spin_lock_irqsave in grgpio_remove > > kernel/irq/irqdomain.c, 243: > mutex_lock in irq_domain_remove > drivers/gpio/gpio-grgpio.c, 463: > irq_domain_remove in grgpio_remove > drivers/gpio/gpio-grgpio.c, 449: > _raw_spin_lock_irqsave in grgpio_remove > > mutex_lock() can sleep at runtime. > > To fix these bugs, gpiochip_remove() and irq_domain_remove() are called > without holding the spinlock. > > These bugs are found by a static analysis tool STCheck written by myself. > > Signed-off-by: Jia-Ju Bai <baijiaju1990@xxxxxxxxx> > --- > drivers/gpio/gpio-grgpio.c | 5 ++++- > sound/soc/sti/uniperif_player.c | 3 ++- > 2 files changed, 6 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c > index 08234e64993a..60a2871c5ba7 100644 > --- a/drivers/gpio/gpio-grgpio.c > +++ b/drivers/gpio/gpio-grgpio.c > @@ -448,13 +448,16 @@ static int grgpio_remove(struct platform_device *ofdev) > } > } > > + spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); > + > gpiochip_remove(&priv->gc); > > if (priv->domain) > irq_domain_remove(priv->domain); > > out: > - spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); > + if (ret) > + spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); In general there is no need for locking in remove() callbacks. I guess you can safely remove the spinlock here all together. > > return ret; > } > diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c > index 48ea915b24ba..62244e207679 100644 > --- a/sound/soc/sti/uniperif_player.c > +++ b/sound/soc/sti/uniperif_player.c > @@ -601,13 +601,14 @@ static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol, > mutex_unlock(&player->ctrl_lock); > > spin_lock_irqsave(&player->irq_lock, flags); > + spin_unlock_irqrestore(&player->irq_lock, flags); Yeah I can tell this was generated automatically - what does this line is expected to achieve? Bart > + > if (player->substream && player->substream->runtime) > uni_player_set_channel_status(player, > player->substream->runtime); > else > uni_player_set_channel_status(player, NULL); > > - spin_unlock_irqrestore(&player->irq_lock, flags); > return 0; > } > > -- > 2.17.1 >