linux-pwm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* PWM regression causing failures with the pwm-atmel driver
@ 2023-05-22 15:19 Peter Rosin
  2023-05-22 16:25 ` Thierry Reding
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Peter Rosin @ 2023-05-22 15:19 UTC (permalink / raw)
  To: LKML, Uwe Kleine-König, linux-pwm
  Cc: Thorsten Leemhuis, Thierry Reding, Conor Dooley, Claudiu Beznea

Hi!

I have a device with a "sound card" that has an amplifier that needs
an extra boost when high amplification is requested. This extra
boost is controlled with a pwm-regulator.

As of commit c73a3107624d ("pwm: Handle .get_state() failures") this
device no longer works. I have tracked the problem to an unfortunate
interaction between the underlying PWM driver and the PWM core.

The driver is drivers/pwm/pwm-atmel.c which has difficulties getting
the period and/or duty_cycle from the HW when the PWM is not enabled.
Because of this, I think, the driver does not fill in .period and
.duty_cycle at all in atmel_pwm_get_state() unless the PWM is enabled.

However, the PWM core is not expecting these fields to be left as-is,
at least not in pwm_adjust_config(), and its local state variable on
the stack ends up with whatever crap was on the stack on entry for
these fields. That fails spectacularly when the function continues to
do math on these uninitialized values.

In particular, I find this in the kernel log when a bad kernel runs:
pwm-regulator: probe of reg-ana failed with error -22

Before commit c73a3107624d this was a silent failure, and the situation
"repaired itself" when the PWM was later reprogrammed, at least for my
case. After that commit, the failure is fatal and the "sound card"
fails to come up at all.


I see a couple of adjustments that could be made.

1. Zero out some fields in the driver:

@@ -390,4 +390,6 @@ static int atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
 		state->enabled = true;
 	} else {
+		state->period = 0;
+		state->duty_cycle = 0;
 		state->enabled = false;
 	}


2. Don't try to "adjust" a disabled PWM:

@@ -656,7 +656,7 @@ int pwm_adjust_config(struct pwm_device *pwm)
 	 * In either case, we setup the new period and polarity, and assign a
 	 * duty cycle of 0.
 	 */
-	if (!state.period) {
+	if (!state.enabled || !state.period) {
 		state.duty_cycle = 0;
 		state.period = pargs.period;
 		state.polarity = pargs.polarity;


3. Zero out the state before calling pwm_get_state:

@@ -115,7 +115,7 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
 	}
 
 	if (pwm->chip->ops->get_state) {
-		struct pwm_state state;
+		struct pwm_state state = { .enabled = true };
 
 		err = pwm->chip->ops->get_state(pwm->chip, pwm, &state);
 		trace_pwm_get(pwm, &state, err);
@@ -448,7 +448,7 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
 {
 	struct pwm_state *last = &pwm->last;
 	struct pwm_chip *chip = pwm->chip;
-	struct pwm_state s1, s2;
+	struct pwm_state s1 = { .enabled = false }, s2;
 	int err;
 
 	if (!IS_ENABLED(CONFIG_PWM_DEBUG))
@@ -634,7 +634,7 @@ EXPORT_SYMBOL_GPL(pwm_capture);
  */
 int pwm_adjust_config(struct pwm_device *pwm)
 {
-	struct pwm_state state;
+	struct pwm_state state = { .enabled = false };
 	struct pwm_args pargs;
 
 	pwm_get_args(pwm, &pargs);
@@ -1119,7 +1119,7 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
 
 	for (i = 0; i < chip->npwm; i++) {
 		struct pwm_device *pwm = &chip->pwms[i];
-		struct pwm_state state;
+		struct pwm_state state = { .enabled = false };
 
 		pwm_get_state(pwm, &state);
 


I have verified that any of the above approaches resolve the
regression but I don't know which approach is best? Maybe more
than one?

However:

Approach 1. will maybe clobber the saved pwm->state such that
it no longer works to get the period/duty_cycle if/when the
PWM is disabled? Maybe only for some corner case? But that might
be a significant corner case?

Approach 2. will maybe mess up some unrelated functionality?

Approach 3. is ugly, intrusive and is in all likelihood
incomplete. It also needs a rebase from the culprit commit.

Cheers,
Peter

#regzbot introduced c73a3107624d

^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: PWM regression causing failures with the pwm-atmel driver
@ 2023-05-23 20:42 Peter Rosin
  2023-05-24  6:07 ` Uwe Kleine-König
  0 siblings, 1 reply; 14+ messages in thread
From: Peter Rosin @ 2023-05-23 20:42 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: LKML, linux-pwm, Thorsten Leemhuis, Thierry Reding, Conor Dooley,
	Claudiu Beznea

2023-05-23 at 01:34, Peter Rosin wrote:
> So, I took a step back and can only conclude that there must be some
> another regression to find, and I was confused by that other regression.
> In short, I was on 6.1.<foo> and everything was fine, and then I bumped
> to 6.3 and a process crashed. I went to 6.2 and that same process also
> crashed. I then totally focused on v6.1..v6.2 to figure out the problem.
> I simply assumed v6.3 had the same problem because the symptom from
> 30.000ft was the same (that process died). I failed to go back to v6.3
> to confirm that it was indeed the same problem as I had found in the
> v6.1..v6.2 range.
> 
> My bad, it seems I have another day of bisections lined up.

For closure, I ended up with this:
https://lore.kernel.org/lkml/221d19e2-6b92-7f38-7d8a-a730f54c33ea@axentia.se/

I.e. another v6.1..v6.2 regression that caused sound failures.
The two problems looked very similar to the suffering application.

Anyway, sorry again for the noise.

Cheers,
Peter

^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: PWM regression causing failures with the pwm-atmel driver
@ 2023-05-24  7:45 Peter Rosin
  0 siblings, 0 replies; 14+ messages in thread
From: Peter Rosin @ 2023-05-24  7:45 UTC (permalink / raw)
  To: Uwe Kleine-König
  Cc: LKML, linux-pwm, Thorsten Leemhuis, Thierry Reding, Conor Dooley,
	Claudiu Beznea

Hi!

2023-05-24 at 08:07, Uwe Kleine-König wrote:
> On Tue, May 23, 2023 at 10:42:34PM +0200, Peter Rosin wrote:
>> 2023-05-23 at 01:34, Peter Rosin wrote:
>>> So, I took a step back and can only conclude that there must be some
>>> another regression to find, and I was confused by that other regression.
>>> In short, I was on 6.1.<foo> and everything was fine, and then I bumped
>>> to 6.3 and a process crashed. I went to 6.2 and that same process also
>>> crashed. I then totally focused on v6.1..v6.2 to figure out the problem.
>>> I simply assumed v6.3 had the same problem because the symptom from
>>> 30.000ft was the same (that process died). I failed to go back to v6.3
>>> to confirm that it was indeed the same problem as I had found in the
>>> v6.1..v6.2 range.
>>>
>>> My bad, it seems I have another day of bisections lined up.
>>
>> For closure, I ended up with this:
>> https://lore.kernel.org/lkml/221d19e2-6b92-7f38-7d8a-a730f54c33ea@axentia.se/
>>
>> I.e. another v6.1..v6.2 regression that caused sound failures.
>> The two problems looked very similar to the suffering application.
>>
>> Anyway, sorry again for the noise.
> 
> OK. After your first mail I had the impression there is another PWM
> releated problem to be reported, but it seems this isn't the case.
> 
> Just to have that explicit: Did I understand you right?

The PWM regression was already solved by 1271a7b98e79 ("pwm: Zero-
initialize the pwm_state passed to driver's .get_state()") and I failed
to notice that. I was simply confused by that other totally unrelated
DMA problem that made me think the PWM problem persisted into the
present when in fact it didn't.

All is well.

Cheers,
Peter

#regzbot fixed-by: 1271a7b98e79

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-06-20 16:30 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-22 15:19 PWM regression causing failures with the pwm-atmel driver Peter Rosin
2023-05-22 16:25 ` Thierry Reding
2023-05-22 17:23 ` Uwe Kleine-König
2023-05-22 19:28   ` Peter Rosin
2023-05-22 20:43     ` Uwe Kleine-König
2023-05-22 23:34       ` Peter Rosin
2023-05-23 20:31       ` Thierry Reding
2023-05-24  6:37         ` Uwe Kleine-König
2023-06-20 14:24 ` Thorsten Leemhuis
2023-06-20 15:43   ` Peter Rosin
2023-06-20 16:30     ` Linux regression tracking #update (Thorsten Leemhuis)
2023-05-23 20:42 Peter Rosin
2023-05-24  6:07 ` Uwe Kleine-König
2023-05-24  7:45 Peter Rosin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).