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

Mark Rutland mark.rutland at arm.com
Wed May 29 08:08:01 PDT 2024


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.



More information about the linux-arm-kernel mailing list