RE: [PATCH v6 2/4] pwm: Add support for RZ/V2M PWM driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Uwe,

Thanks for your reply!

> From: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx>
> Sent: Saturday, February 10, 2024 5:27 PM
> To: Fabrizio Castro <fabrizio.castro.jz@xxxxxxxxxxx>
> Subject: Re: [PATCH v6 2/4] pwm: Add support for RZ/V2M PWM driver
> 
> Hello Fabrizio,
> 
> On Thu, Feb 08, 2024 at 11:24:09PM +0000, Fabrizio Castro wrote:
> > +static inline u64 rzv2m_pwm_mul_u64_u64_div_u64_roundup(u64 a, u64 b,
> u64 c)
> > +{
> > +	u64 ab = a * b;
> 
> This might overflow.

In the context of this driver, this cannot overflow.
The 2 formulas the above is needed for are:
1) period = (cyc + 1)*(NSEC_PER_SEC * frequency_divisor)/rate
2) duty_cycle = (cyc + 1 - low)*(NSEC_PER_SEC * frequency_divisor)/rate

With respect to 1), the dividend overflows when period * rate also
overflows (its product is calculated in rzv2m_pwm_config).
However, limiting the period to a maximum value of U64_MAX / rate
prevents the calculations from overflowing (in both directions, from period to cyc, and from cyc to period). v6 uses max_period for this.
The situation for 2) is very similar to 1), with duty_cycle<=period,
therefore limiting period to a max value (and clamping the duty cycle
accordingly) will ensure that the calculation for duty_cycle won't
overflow, either.

> 
> > +	return ab / c + (ab % c ? 1 : 0);
> 
> This division triggered the kernel build bot error. If you want to
> divide a u64, you must not use /.

Right!
I have replicated the problem locally, and confirmed that also other divisions from the same patch are problematic.
Clearly, % can't work either.

I am going to replace / with div64_u64.
For rounding up, I think I'll go with something like:

u64 ab = a * b;
u64 d = div64_u64(ab, c);
u64 e = d * c;
return d + ((ab - e) ? 1 : 0);

I am aware that I could use DIV64_U64_ROUND_UP instead of the above,
however, the above allows for larger dividends than when using DIV64_U64_ROUND_UP.
If I were to use DIV64_U64_ROUND_UP instead, I would have to limit
max_period further to (U64_MAX + 1 - rate)/rate, which I rather avoid.

I'll send v7 to address this build issue for 32 bit platforms.

Cheers,
Fab

> 
> Best regards
> Uwe
> 
> --
> Pengutronix e.K.                           | Uwe Kleine-König            |
> Industrial Linux Solutions                 | https://www.pengutronix.de/ |





[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux