Message ID | 20200109233106.17060-1-peron.clem@gmail.com (mailing list archive) |
---|---|
State | Mainlined |
Commit | 3e954d9626895d374704bb49a8fb538a974ebcf5 |
Headers | show |
Series | [RFC] pwm: sun4i: Move pwm_calculate out of spin_lock | expand |
Hello Clément, On Fri, Jan 10, 2020 at 12:31:06AM +0100, Clément Péron wrote: > pwm_calculate calls clk_get_rate while holding a spin_lock. > > This create an issue as clk_get_rate() may sleep. Slightly orthogonal to this issue, it might be a good idea to add a might_sleep() to clk_get_rate(). (Added clk maintainers to Cc: for this suggestion.) > Move pwm_calculate out of this spin_lock. > > Fixes: c32c5c50d4fe ("pwm: sun4i: Switch to atomic PWM") > Reported-by: Alex Mobigo <alex.mobigo@gmail.com> > Suggested-by: Vasily Khoruzhick <anarsoul@gmail.com> > Signed-off-by: Clément Péron <peron.clem@gmail.com> > --- > > Hi, > > this issue has been reported on linux-sunxi Google groups. > > I don't have a board with PWM to confirm it. > > Please wait a tested-by. > > Thanks, > Clément > > drivers/pwm/pwm-sun4i.c | 7 +++---- > 1 file changed, 3 insertions(+), 4 deletions(-) > > diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c > index 1afd41ebd3fd..6b230029dc49 100644 > --- a/drivers/pwm/pwm-sun4i.c > +++ b/drivers/pwm/pwm-sun4i.c > @@ -248,19 +248,18 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, > } > } > > - spin_lock(&sun4i_pwm->ctrl_lock); > - ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); > - > ret = sun4i_pwm_calculate(sun4i_pwm, state, &duty, &period, &prescaler, > &bypass); > if (ret) { > dev_err(chip->dev, "period exceeds the maximum value\n"); > - spin_unlock(&sun4i_pwm->ctrl_lock); > if (!cstate.enabled) > clk_disable_unprepare(sun4i_pwm->clk); > return ret; > } > > + spin_lock(&sun4i_pwm->ctrl_lock); > + ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); > + > if (sun4i_pwm->data->has_direct_mod_clk_output) { > if (bypass) { > ctrl |= BIT_CH(PWM_BYPASS, pwm->hwpwm); As sun4i_pwm_calculate does nothing that depends on (or modifies) hardware state (apart from clk_get_rate(sun4i_pwm->clk) which can be assumed to be constant) the change looks good. Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Best regards Uwe
On Thu, Jan 9, 2020 at 8:31 PM Clément Péron <peron.clem@gmail.com> wrote: > > pwm_calculate calls clk_get_rate while holding a spin_lock. > > This create an issue as clk_get_rate() may sleep. > > Move pwm_calculate out of this spin_lock. > > Fixes: c32c5c50d4fe ("pwm: sun4i: Switch to atomic PWM") > Reported-by: Alex Mobigo <alex.mobigo@gmail.com> > Suggested-by: Vasily Khoruzhick <anarsoul@gmail.com> > Signed-off-by: Clément Péron <peron.clem@gmail.com> > --- > > Hi, > > this issue has been reported on linux-sunxi Google groups. > > I don't have a board with PWM to confirm it. > > Please wait a tested-by. > > Thanks, > Clément > > drivers/pwm/pwm-sun4i.c | 7 +++---- > 1 file changed, 3 insertions(+), 4 deletions(-) > > diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c > index 1afd41ebd3fd..6b230029dc49 100644 > --- a/drivers/pwm/pwm-sun4i.c > +++ b/drivers/pwm/pwm-sun4i.c > @@ -248,19 +248,18 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, > } > } > > - spin_lock(&sun4i_pwm->ctrl_lock); > - ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); > - > ret = sun4i_pwm_calculate(sun4i_pwm, state, &duty, &period, &prescaler, > &bypass); > if (ret) { > dev_err(chip->dev, "period exceeds the maximum value\n"); > - spin_unlock(&sun4i_pwm->ctrl_lock); > if (!cstate.enabled) > clk_disable_unprepare(sun4i_pwm->clk); > return ret; > } > > + spin_lock(&sun4i_pwm->ctrl_lock); > + ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); > + > if (sun4i_pwm->data->has_direct_mod_clk_output) { > if (bypass) { > ctrl |= BIT_CH(PWM_BYPASS, pwm->hwpwm); > -- > 2.20.1 > """"""""""""""""" Tested on my board Pine64+, problems occurs before the patch but not after... Tested-By: Alexander Finger <alex.mobigo@gmail.com> """""""""""""""
Hi, On Mon, 13 Jan 2020 at 01:40, Alexander <alex.mobigo@gmail.com> wrote: > > On Thu, Jan 9, 2020 at 8:31 PM Clément Péron <peron.clem@gmail.com> wrote: > > > > pwm_calculate calls clk_get_rate while holding a spin_lock. > > > > This create an issue as clk_get_rate() may sleep. > > > > Move pwm_calculate out of this spin_lock. > > > > Fixes: c32c5c50d4fe ("pwm: sun4i: Switch to atomic PWM") > > Reported-by: Alex Mobigo <alex.mobigo@gmail.com> > > Suggested-by: Vasily Khoruzhick <anarsoul@gmail.com> > > Signed-off-by: Clément Péron <peron.clem@gmail.com> > > --- > > > > Hi, > > > > this issue has been reported on linux-sunxi Google groups. > > > > I don't have a board with PWM to confirm it. > > > > Please wait a tested-by. > > > > Thanks, > > Clément > > > > drivers/pwm/pwm-sun4i.c | 7 +++---- > > 1 file changed, 3 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c > > index 1afd41ebd3fd..6b230029dc49 100644 > > --- a/drivers/pwm/pwm-sun4i.c > > +++ b/drivers/pwm/pwm-sun4i.c > > @@ -248,19 +248,18 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, > > } > > } > > > > - spin_lock(&sun4i_pwm->ctrl_lock); > > - ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); > > - > > ret = sun4i_pwm_calculate(sun4i_pwm, state, &duty, &period, &prescaler, > > &bypass); > > if (ret) { > > dev_err(chip->dev, "period exceeds the maximum value\n"); > > - spin_unlock(&sun4i_pwm->ctrl_lock); > > if (!cstate.enabled) > > clk_disable_unprepare(sun4i_pwm->clk); > > return ret; > > } > > > > + spin_lock(&sun4i_pwm->ctrl_lock); > > + ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); > > + > > if (sun4i_pwm->data->has_direct_mod_clk_output) { > > if (bypass) { > > ctrl |= BIT_CH(PWM_BYPASS, pwm->hwpwm); > > -- > > 2.20.1 > > > """"""""""""""""" > Tested on my board Pine64+, problems occurs before the patch but not after... > > Tested-By: Alexander Finger <alex.mobigo@gmail.com> Thanks, I will send a v2 with your proper name for the Reported-by tag Regards, Clement > """""""""""""""
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c index 1afd41ebd3fd..6b230029dc49 100644 --- a/drivers/pwm/pwm-sun4i.c +++ b/drivers/pwm/pwm-sun4i.c @@ -248,19 +248,18 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, } } - spin_lock(&sun4i_pwm->ctrl_lock); - ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); - ret = sun4i_pwm_calculate(sun4i_pwm, state, &duty, &period, &prescaler, &bypass); if (ret) { dev_err(chip->dev, "period exceeds the maximum value\n"); - spin_unlock(&sun4i_pwm->ctrl_lock); if (!cstate.enabled) clk_disable_unprepare(sun4i_pwm->clk); return ret; } + spin_lock(&sun4i_pwm->ctrl_lock); + ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); + if (sun4i_pwm->data->has_direct_mod_clk_output) { if (bypass) { ctrl |= BIT_CH(PWM_BYPASS, pwm->hwpwm);
pwm_calculate calls clk_get_rate while holding a spin_lock. This create an issue as clk_get_rate() may sleep. Move pwm_calculate out of this spin_lock. Fixes: c32c5c50d4fe ("pwm: sun4i: Switch to atomic PWM") Reported-by: Alex Mobigo <alex.mobigo@gmail.com> Suggested-by: Vasily Khoruzhick <anarsoul@gmail.com> Signed-off-by: Clément Péron <peron.clem@gmail.com> --- Hi, this issue has been reported on linux-sunxi Google groups. I don't have a board with PWM to confirm it. Please wait a tested-by. Thanks, Clément drivers/pwm/pwm-sun4i.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)