Linux PWM subsystem development
 help / color / mirror / Atom feed
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.


  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