Re: [PATCH] arm64/io: add constant-argument check

From: Mark Rutland
Date: Wed May 29 2024 - 11:08:16 EST


On Wed, May 29, 2024 at 02:29:37PM +0200, Arnd Bergmann wrote:
> On Wed, May 29, 2024, at 13:14, Mark Rutland wrote:
> >> {
> >> - if (count == 8 || count == 4 || count == 2 || count == 1) {
> >> + if (__builtin_constant_p(count) &&
> >> + (count == 8 || count == 4 || count == 2 || count == 1)) {
> >> __const_memcpy_toio_aligned32(to, from, count);
> >> dgh();
> >> } else {
> >
> > I don't think this is the right fix.
> >
> > The idea was that this was checked in __iowrite32_copy(), which does:
> >
> > #define __iowrite32_copy(to, from, count) \
> > (__builtin_constant_p(count) ? \
> > __const_iowrite32_copy(to, from, count) : \
> > __iowrite32_copy_full(to, from, count))
> >
> > ... and so __const_iowrite32_copy() should really be marked as __always_inline,
> > and the same for __const_memcpy_toio_aligned32(), to guarantee that both get
> > inlined and such that __const_memcpy_toio_aligned32() sees a constant.
> >
> > The same reasoning applies to __const_iowrite64_copy() and
> > __const_memcpy_toio_aligned64().
> >
> > Checking for a constant in __const_iowrite32_copy() doesn't guarantee
> > that __const_memcpy_toio_aligned32() is inlined and will actually see a
> > constant.
> >
> > Does diff the below you for you?
>
> Yes, your version addresses both failures I ran into, and
> I think all other theoretical cases.
>
> I would prefer to combine both though, using __always_inline
> to force the compiler to pick the inline version over
> __iowrite32_copy_full() even when it is optimizing for size
> and it decides the inline version is larger, but removing
> the extra complexity from the macro.

Sorry, I'm not sure what you mean here. I don't see anything handling
optimizing for size today so I'm not sure what change your suggesting to
force the use of the inline version; AFAICT that'd always be forced for
a suitable constant size.

What change are you suggesting?

> According to Jason, he used a macro here to be sure
> that the compiler can detect an inline function argument
> as constant when the value is known but it is not
> a constant value according to the C standard.
>
> This was indeed a problem in older versions of clang
> that missed a lot of optimizations in the kernel, but
> clang-8 and higher were changed to have the same behavior
> as gcc here, so it is no longer necessary now that the
> older versions are unable to build kernels.

Getting rid of the macro is fine by me.

Mark.