From: David Lechner <dlechner@baylibre.com>
To: "Uwe Kleine-König" <u.kleine-koenig@baylibre.com>
Cc: linux-pwm@vger.kernel.org, Trevor Gamblin <tgamblin@baylibre.com>
Subject: Re: [PATCH v2 4/8] pwm: Provide new consumer API functions for waveforms
Date: Tue, 16 Jul 2024 09:28:32 -0500 [thread overview]
Message-ID: <23a181c4-80b1-4545-ad48-54e89e4bf690@baylibre.com> (raw)
In-Reply-To: <cwgrbvzc73hnsmkfigq2t5t43y73oyz54tugad6ayxwzrlawlw@qd3bylzfqvns>
On 7/16/24 2:06 AM, Uwe Kleine-König wrote:
> Hello David,
>
> On Mon, Jul 15, 2024 at 05:23:45PM -0500, David Lechner wrote:
>> On 7/15/24 6:16 AM, Uwe Kleine-König wrote:
>>> Provide API functions for consumers to work with waveforms.
>>>
>>> Note that one relevant difference between pwm_get_state() and
>>> pwm_get_waveform*() is that the latter yields the actually configured
>>> hardware state, while the former yields the last state passed to
>>> pwm_apply*() and so doesn't account for hardware specific rounding.
>>>
>>
>> ...
>>
>>> +
>>> +/* PWM consumer APIs */
>>> +int pwm_round_waveform_might_sleep(struct pwm_device *pwm, struct pwm_waveform *wf);
>>> +int pwm_get_waveform_might_sleep(struct pwm_device *pwm, struct pwm_waveform *wf);
>>> +int pwm_set_waveform_might_sleep(struct pwm_device *pwm, const struct pwm_waveform *wf, bool exact);
>>> int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state);
>>> int pwm_apply_atomic(struct pwm_device *pwm, const struct pwm_state *state);
>>> int pwm_adjust_config(struct pwm_device *pwm);
>>
>>
>> It seems like there could be a potential race condition between rounding
>> and setting a PWM.
>>
>> Consider two PWM devices that share the same clock and the driver can
>> set the clock rate to accommodate a wider range of periods or get a
>> more accurate duty length.
>>
>> Thread 1 Thread 2
>> -------- --------
>> PWM consumer A calls round_waveform()
>> a few times, e.g. to round up or round
>> closest. Clock is not exclusive so
>> rounding assumes the rate can be
>> changed to get the best rate.
>> PWM consumer B call set_waveform().
>> clk_set_rate_exclusive() is called
>> on the clock so the rate can no
>> longer be changed and the rate is
>> not the one PWM consumer A selected
>> in the rounding operation.
>> PWM consumer A calls set_waveform().
>> This will either fail or will
>> not get the same results that
>> was returned by round_waveform().
>
> The "exact" parameter has the purpose to make this fail. While
> implementing the idea I wondered if I should drop the parameter and
> make .set_waveform() imply exact=true.
Would consumers then be expected to implement a retry loop to
handle the error when an exact=true call failed because the same
rounding was no longer possible?
>
> Two more thoughts about this: First, I think the most usual use cases
> are rounding up or maybe rounding closest (instead of rounding down as
> done by default). It's easy to implement a helper function in the pwm
> core that holds the chip lock and does the necessary function calls to
> determine the rounded setting needed.
Would these same functions also get ioctls for the cdev interface?
>
> The second thought is: Even when holding the chip lock, another clk
> consumer can theoretically change the flexibility of a participating clk
> while the right settings are determined for a given pwm consumer. Also
> if I use clk_round_rate() to determine the resulting rate of a parent
> clock, it's not sure that I can set this rate because again the
> situation might have changed since I called clk_round_rate() or because
> another consumer refuses my request to change the rate.
>
> So as soon as you consider changing an upstream clock to reach a certain
> PWM setting, this all degrades to a racy best effort quest.
>
>> If it wasn't for the userspace cdev interface, I would suggest
>> to drop pwm_round_waveform_might_sleep() and pass an optional
>> function pointer to pwm_set_waveform_might_sleep() instead of
>> the `bool exact` argument so that the full operation of rounding
>> and setting could be performed with the pwmchip lock held without
>> consumer drivers having to worry about getting it right. Consumer
>> drivers would then just have to implement functions to suit their
>> needs, or there could even be standard ones like round_closest().
>>
>> But that still might not fix it in all cases e.g. if two pwmchips
>> share the same clock as opposed to one pwmchip with two outputs.
>> If this is possible, then then "pwm: Add more locking" patch
>> might already cause some problems with race conditions in the
>> existing PWM apply() ops. Although, I suppose this kind of
>> clock coordination between pwm chips (and potentially other
>> devices) should be handled outside of the PWM subsystem.
>
> I would expect that the "Add more locking" patch doesn't enable more
> races than are possible without it? I don't understand the problems you
> think of here.
>
When we consider other non-PWM clock consumers you are right, it
is not any different that before. I think you understood me fully.
I agree that there aren't any serious issues here any more than
the current state of things.
next prev parent reply other threads:[~2024-07-16 14:28 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-15 11:16 [PATCH v2 0/8] pwm: New abstraction and userspace API Uwe Kleine-König
2024-07-15 11:16 ` [PATCH v2 1/8] pwm: Simplify pwm_capture() Uwe Kleine-König
2024-07-15 11:16 ` [PATCH v2 2/8] pwm: Add more locking Uwe Kleine-König
2024-07-15 16:56 ` David Lechner
2024-07-15 20:08 ` Uwe Kleine-König
2024-07-15 11:16 ` [PATCH v2 3/8] pwm: New abstraction for PWM waveforms Uwe Kleine-König
2024-07-15 18:55 ` David Lechner
2024-07-15 20:17 ` Uwe Kleine-König
2024-07-16 7:29 ` Nuno Sá
2024-07-15 11:16 ` [PATCH v2 4/8] pwm: Provide new consumer API functions for waveforms Uwe Kleine-König
2024-07-15 22:23 ` David Lechner
2024-07-16 7:06 ` Uwe Kleine-König
2024-07-16 14:28 ` David Lechner [this message]
2024-07-17 9:13 ` Uwe Kleine-König
2024-07-15 11:16 ` [PATCH v2 5/8] pwm: Add support for pwmchip devices for faster and easier userspace access Uwe Kleine-König
2024-07-15 19:37 ` David Lechner
2024-07-15 19:52 ` Uwe Kleine-König
2024-07-30 10:26 ` Uwe Kleine-König
2024-07-30 18:41 ` David Lechner
2024-07-31 6:49 ` Uwe Kleine-König
2024-07-15 11:16 ` [PATCH v2 6/8] pwm: Add tracing for waveform callbacks Uwe Kleine-König
2024-07-15 11:16 ` [PATCH v2 7/8] pwm: axi-pwmgen: Implementation of the " Uwe Kleine-König
2024-07-15 11:16 ` [PATCH v2 8/8] pwm: stm32: " 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=23a181c4-80b1-4545-ad48-54e89e4bf690@baylibre.com \
--to=dlechner@baylibre.com \
--cc=linux-pwm@vger.kernel.org \
--cc=tgamblin@baylibre.com \
--cc=u.kleine-koenig@baylibre.com \
/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