From: Thierry Reding <thierry.reding@gmail.com>
To: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
Cc: linux-pwm@vger.kernel.org, kernel@pengutronix.de,
Bartosz Golaszewski <brgl@bgdev.pl>,
Andy Shevchenko <andy@kernel.org>
Subject: Re: [PATCH v1 101/101] pwm: Add more locking
Date: Fri, 6 Oct 2023 12:09:59 +0200 [thread overview]
Message-ID: <ZR_c99evPTimrQY9@orome.fritz.box> (raw)
In-Reply-To: <20230808171931.944154-102-u.kleine-koenig@pengutronix.de>
[-- Attachment #1: Type: text/plain, Size: 6149 bytes --]
On Tue, Aug 08, 2023 at 07:19:31PM +0200, Uwe Kleine-König wrote:
> This ensures that a pwm_chip that has no corresponding driver isn't used
> and that a driver doesn't go away while a callback is still running.
>
> As with the previous commit this was not expected to be a problem in the
> presence of device links, but still it can happen with the command
> sequence mentioned in the previous commit. Even if this should turn out
> to be a problem that could be fixed by improving device links, this is a
> necessary preparation to create race-free pwmchip character devices.
>
> A not so nice side effect is that all calls to the PWM API are
> serialized now. If this turns out to be problematic this can be replaced
> by per-pwm_chip locking later. As long as this bottleneck isn't known to
> be a problem in practise, the simpler approach of a single lock is used
> here.
>
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> ---
> drivers/pwm/core.c | 50 ++++++++++++++++++++++++++++++++++++---------
> include/linux/pwm.h | 2 ++
> 2 files changed, 42 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
> index fcf30f77da34..66743ded66f6 100644
> --- a/drivers/pwm/core.c
> +++ b/drivers/pwm/core.c
> @@ -230,6 +230,7 @@ static struct pwm_chip *pwmchip_alloc(struct device *parent, unsigned int npwm,
> dev->release = pwmchip_release;
>
> chip->npwm = npwm;
> + chip->ready = false;
>
> for (i = 0; i < chip->npwm; i++) {
> struct pwm_device *pwm = &chip->pwms[i];
> @@ -309,6 +310,8 @@ int __pwmchip_add(struct pwm_chip *chip, struct module *owner)
> module_put(owner);
> }
>
> + chip->ready = true;
> +
> mutex_unlock(&pwm_lock);
>
> return ret;
> @@ -324,12 +327,25 @@ EXPORT_SYMBOL_GPL(__pwmchip_add);
> void pwmchip_remove(struct pwm_chip *chip)
> {
> pwmchip_sysfs_unexport(chip);
> + unsigned int i;
This looks weird, mixing declarations and code.
>
> if (IS_ENABLED(CONFIG_OF))
> of_pwmchip_remove(chip);
>
> mutex_lock(&pwm_lock);
>
> + for (i = 0; i < chip->npwm; ++i) {
> + struct pwm_device *pwm = &chip->pwms[i];
> +
> + if (test_and_clear_bit(PWMF_REQUESTED, &pwm->flags)) {
> + dev_alert(&chip->dev, "Freeing requested pwm #%u\n", i);
s/pwm #%u/PWM #%u/
> + if (pwm->chip->ops->free)
> + pwm->chip->ops->free(pwm->chip, pwm);
> + }
> + }
> +
> + chip->ready = false;
> +
> idr_remove(&pwmchip_idr, chip->id);
>
> mutex_unlock(&pwm_lock);
> @@ -505,7 +521,7 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
> int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
> {
> struct pwm_chip *chip;
> - int err;
> + int err = 0;
>
> /*
> * Some lowlevel driver's implementations of .apply() make use of
> @@ -522,17 +538,24 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
>
> chip = pwm->chip;
>
> + mutex_lock(&pwm_lock);
> +
> + if (!chip->ready) {
> + err = -ENXIO;
> + goto out_unlock;
> + }
> +
> if (state->period == pwm->state.period &&
> state->duty_cycle == pwm->state.duty_cycle &&
> state->polarity == pwm->state.polarity &&
> state->enabled == pwm->state.enabled &&
> state->usage_power == pwm->state.usage_power)
> - return 0;
> + goto out_unlock;
>
> err = chip->ops->apply(chip, pwm, state);
> trace_pwm_apply(pwm, state, err);
> if (err)
> - return err;
> + goto out_unlock;
>
> pwm->state = *state;
>
> @@ -542,7 +565,10 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
> */
> pwm_apply_state_debug(pwm, state);
>
> - return 0;
> +out_unlock:
> + mutex_unlock(&pwm_lock);
> +
> + return err;
> }
> EXPORT_SYMBOL_GPL(pwm_apply_state);
>
> @@ -566,7 +592,12 @@ int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result,
> return -ENOSYS;
>
> mutex_lock(&pwm_lock);
> - err = pwm->chip->ops->capture(pwm->chip, pwm, result, timeout);
> +
> + if (pwm->chip->ready)
> + err = pwm->chip->ops->capture(pwm->chip, pwm, result, timeout);
> + else
> + err = -ENXIO;
> +
> mutex_unlock(&pwm_lock);
>
> return err;
> @@ -978,18 +1009,17 @@ void pwm_put(struct pwm_device *pwm)
>
> mutex_lock(&pwm_lock);
>
> - if (!test_and_clear_bit(PWMF_REQUESTED, &pwm->flags)) {
> - pr_warn("PWM device already freed\n");
Don't we want to keep this message? We do want to make sure that we're
always calling things in the right order and this might help catch
errors.
> + if (!test_and_clear_bit(PWMF_REQUESTED, &pwm->flags))
> goto out;
> - }
>
> - if (pwm->chip->ops->free)
> + if (pwm->chip->ready && pwm->chip->ops->free)
> pwm->chip->ops->free(pwm->chip, pwm);
These callbacks may do things like decrease internal reference counts or
free memory, etc. Don't we want to run those even if the PWM chip isn't
operational anymore? Wouldn't we otherwise risk leaking memory and/or
other resources?
>
> pwm->label = NULL;
>
> - put_device(&pwm->chip->dev);
> out:
> + put_device(&pwm->chip->dev);
> +
> mutex_unlock(&pwm_lock);
> }
> EXPORT_SYMBOL_GPL(pwm_put);
> diff --git a/include/linux/pwm.h b/include/linux/pwm.h
> index 3dd46b89ab8b..f5b65994a30e 100644
> --- a/include/linux/pwm.h
> +++ b/include/linux/pwm.h
> @@ -289,6 +289,7 @@ struct pwm_ops {
> * @of_pwm_n_cells: number of cells expected in the device tree PWM specifier
> * @list: list node for internal use
> * @pwms: array of PWM devices allocated by the framework
> + * @ready: tracks if the chip is operational
> */
> struct pwm_chip {
> struct device dev;
> @@ -302,6 +303,7 @@ struct pwm_chip {
> unsigned int of_pwm_n_cells;
>
> /* only used internally by the PWM framework */
> + bool ready;
Can we find a better name for this? Maybe something like "available" or
"operational"? Those are a bit longer, but I feel like they convey more
accurately what's going on. In other words, "ready" is very vague.
Thierry
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2023-10-06 10:10 UTC|newest]
Thread overview: 129+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-08 17:17 [PATCH v1 000/101] pwm: Fix lifetime issues for pwm_chips Uwe Kleine-König
2023-08-08 17:17 ` [PATCH v1 001/101] pwm: Provide devm_pwmchip_alloc() function Uwe Kleine-König
2023-10-06 9:23 ` Thierry Reding
2023-10-06 10:56 ` Uwe Kleine-König
2023-10-06 11:08 ` Thierry Reding
2023-10-06 12:36 ` Uwe Kleine-König
2023-08-08 17:17 ` [PATCH v1 002/101] pwm: ab8500: Make use of " Uwe Kleine-König
2023-08-08 17:17 ` [PATCH v1 003/101] pwm: apple: " Uwe Kleine-König
2023-08-08 17:17 ` [PATCH v1 004/101] pwm: atmel-hlcdc: " Uwe Kleine-König
2023-08-08 17:17 ` [PATCH v1 005/101] pwm: atmel: " Uwe Kleine-König
2023-08-08 17:17 ` [PATCH v1 006/101] pwm: atmel-tcb: " Uwe Kleine-König
2023-08-08 17:17 ` [PATCH v1 007/101] pwm: bcm2835: " Uwe Kleine-König
2023-08-08 17:17 ` [PATCH v1 008/101] pwm: bcm-iproc: " Uwe Kleine-König
2023-08-08 17:17 ` [PATCH v1 009/101] pwm: bcm-kona: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 010/101] pwm: berlin: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 011/101] pwm: brcmstb: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 012/101] pwm: clk: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 013/101] pwm: clps711x: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 014/101] pwm: crc: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 015/101] pwm: cros-ec: Change prototype of helper to prepare further changes Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 016/101] pwm: cros-ec: Make use of devm_pwmchip_alloc() function Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 017/101] pwm: dwc: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 018/101] pwm: ep93xx: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 019/101] pwm: fsl-ftm: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 020/101] pwm: hibvt: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 021/101] pwm: img: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 022/101] pwm: imx1: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 023/101] pwm: imx27: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 024/101] pwm: imx-tpm: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 025/101] pwm: intel-lgm: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 026/101] pwm: iqs620a: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 027/101] pwm: jz4740: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 028/101] pwm: keembay: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 029/101] pwm: lp3943: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 030/101] pwm: lpc18xx-sct: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 031/101] pwm: lpc32xx: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 032/101] pwm: lpss-*: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 033/101] pwm: mediatek: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 034/101] pwm: meson: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 035/101] pwm: microchip-core: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 036/101] pwm: mtk-disp: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 037/101] pwm: mxs: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 038/101] pwm: ntxec: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 039/101] pwm: omap-dmtimer: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 040/101] pwm: pca9685: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 041/101] pwm: pxa: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 042/101] pwm: raspberrypi-poe: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 043/101] pwm: rcar: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 044/101] pwm: renesas-tpu: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 045/101] pwm: rockchip: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 046/101] pwm: rz-mtu3: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 047/101] pwm: samsung: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 048/101] pwm: sifive: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 049/101] pwm: sl28cpld: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 050/101] pwm: spear: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 051/101] pwm: sprd: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 052/101] pwm: sti: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 053/101] pwm: stm32-lp: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 054/101] pwm: stm32: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 055/101] pwm: stmpe: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 056/101] pwm: sun4i: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 057/101] pwm: sunplus: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 058/101] pwm: tegra: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 059/101] pwm: tiecap: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 060/101] pwm: tiehrpwm: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 061/101] pwm: twl-led: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 062/101] pwm: twl: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 063/101] pwm: visconti: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 064/101] pwm: vt8500: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 065/101] pwm: xilinx: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 066/101] gpio: mvebu: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 067/101] drm/bridge: ti-sn65dsi86: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 068/101] leds: qcom-lpg: " Uwe Kleine-König
2023-08-08 17:18 ` [PATCH v1 069/101] staging: greybus: pwm: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 070/101] pwm: Ensure a struct pwm have the same lifetime as its pwm_chip Uwe Kleine-König
2023-10-06 9:38 ` Thierry Reding
2023-10-06 11:04 ` Uwe Kleine-König
2023-10-06 11:16 ` Thierry Reding
2023-10-06 17:04 ` Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 071/101] pwm: ab8500: Store parent device in driver data Uwe Kleine-König
2023-10-06 9:41 ` Thierry Reding
2023-10-06 11:09 ` Uwe Kleine-König
2023-10-06 11:20 ` Thierry Reding
2023-10-06 21:16 ` Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 072/101] pwm: atmel: Stop using struct pwm_chip::dev Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 073/101] pwm: dwc: Store parent device in driver data Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 074/101] pwm: ep93xx: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 075/101] pwm: fsl-ftm: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 076/101] pwm: img: Make use of parent device pointer " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 077/101] pwm: imx27: Store parent device " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 078/101] pwm: jz4740: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 079/101] pwm: lpc18xx-sct: Make use of parent device pointer " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 080/101] pwm: lpss: Store parent device " Uwe Kleine-König
2023-08-08 17:49 ` Andy Shevchenko
2023-08-09 6:10 ` Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 081/101] pwm: mediatek: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 082/101] pwm: meson: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 083/101] pwm: mtk-disp: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 084/101] pwm: omap: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 085/101] pwm: pca9685: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 086/101] pwm: raspberrypi-poe: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 087/101] pwm: rcar: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 088/101] pwm: rz-mtu3: Make use of parent device pointer " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 089/101] pwm: samsung: Store parent device " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 090/101] pwm: sifive: Make use of parent device pointer " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 091/101] pwm: stm32: Store parent device " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 092/101] pwm: stmpe: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 093/101] pwm: sun4i: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 094/101] pwm: tiecap: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 095/101] pwm: tiehrpwm: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 096/101] pwm: twl: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 097/101] pwm: twl-led: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 098/101] pwm: vt8500: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 099/101] staging: greybus: pwm: " Uwe Kleine-König
2023-08-08 17:19 ` [PATCH v1 100/101] pwm: Ensure the memory backing a PWM chip isn't freed while used Uwe Kleine-König
2023-10-06 12:37 ` Thierry Reding
2023-10-06 13:16 ` Uwe Kleine-König
2023-10-06 13:35 ` Andy Shevchenko
2023-08-08 17:19 ` [PATCH v1 101/101] pwm: Add more locking Uwe Kleine-König
2023-10-06 10:09 ` Thierry Reding [this message]
2023-10-06 11:14 ` Uwe Kleine-König
2023-09-26 10:06 ` [PATCH v1 000/101] pwm: Fix lifetime issues for pwm_chips Uwe Kleine-König
2023-10-01 11:10 ` Uwe Kleine-König
2023-10-06 10:15 ` Thierry Reding
2023-10-06 17:05 ` Uwe Kleine-König
2023-10-06 9:20 ` Thierry Reding
2023-10-06 10:41 ` Uwe Kleine-König
2023-10-06 11:50 ` Thierry Reding
2023-10-06 17:35 ` Uwe Kleine-König
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZR_c99evPTimrQY9@orome.fritz.box \
--to=thierry.reding@gmail.com \
--cc=andy@kernel.org \
--cc=brgl@bgdev.pl \
--cc=kernel@pengutronix.de \
--cc=linux-pwm@vger.kernel.org \
--cc=u.kleine-koenig@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox