Re: [PATCH] ARM: mm: fix no-MMU ZERO_PAGE() implementation

From: Giulio Benetti
Date: Tue Oct 18 2022 - 18:33:01 EST


On 18/10/22 20:35, Arnd Bergmann wrote:
On Tue, Oct 18, 2022, at 19:44, Giulio Benetti wrote:
On 18/10/22 09:03, Arnd Bergmann wrote:
On Tue, Oct 18, 2022, at 1:37 AM, Giulio Benetti wrote:
Actually in no-MMU SoCs(i.e. i.MXRT) ZERO_PAGE(vaddr) expands to

It looks like we dropped the ball on this when it came up last.
I'm also not sure when we started requiring this, any idea?

No to be honest. But in my case I've met ZERO_PAGE() calling in sdhci
driver. And as stated on the ML link above:
```
But I wonder if it's safe for noMMU architectures to go on without a
working ZERO_PAGE(0). It has uses scattered throughout the tree, in
drivers, fs, crypto and more, and it's not at all obvious (to me) that
they all depend on CONFIG_MMU.
```
And I've found this driver that requires it and probably is not the last
since imxrt support is not complete.

I can see that microblaze-nommu used BUG() in ZERO_PAGE(), so at
whenever microblaze last worked, we clearly did not call it.

This probably means that microblaze-nommu doesn't use drivers or other
subsystems that require ZERO_PAGE().

To clarify: microblaze-nommu support was removed two years ago,
and probably was already broken for a while before that.

In addition to your fix, I see that arm is the only architecture
that defines 'empty_zero_page' as a pointer to the page, when
everything else just makes it a pointer to the data itself,
or an 'extern char empty_zero_page[]' array, which we may want
to change for consistency.

I was about doing it, but then I tought to move one piece at a time.

Right, it would definitely be a separate patch, but it
can be a series of two patches. We probably wouldn't need to
backport the second patch that turns it into a static allocation.

I've sent the patchset of 2:
https://lore.kernel.org/all/20221018222503.90118-1-giulio.benetti@xxxxxxxxxxxxxxxxxxxxxx/T/#t

I'm wondering if it makes sense to send a patchset for all those
architectures that have only one zero page. I've seen that for example
loongarch has more than one. But for the others I find the array
approach more linear, with less code all around and a bit faster in term
of code execution(of course really few, but better than nothing) since
that array is in .bss, so it will be zeroed earlier during a long
"memset" where assembly instructions for zeroing 8 bytes at a time are
used. What about this?

But yes, I can modify accordingly. That way we also avoid the early
allocation in pagint_init() since it would be a .bss array.

There are three references to empty_zero_page in architecture
independent code, and while we don't seem to use any of them
on Arm, they would clearly be wrong if we did:

drivers/acpi/scan.c:#define INVALID_ACPI_HANDLE ((acpi_handle)empty_zero_page)
drivers/spi/spi-fsl-cpm.c: mspi->dma_dummy_tx = dma_map_single(dev, empty_zero_page, PAGE_SIZE,
include/linux/raid/pq.h:# define raid6_empty_zero_page empty_zero_page

For them I can send patches to substitute with PAGE_ZERO(0) correctly
adapted.

What do you think?

That sounds like a good idea as well.

I've just sent a patchset for this:
https://lore.kernel.org/all/20221018215755.33566-1-giulio.benetti@xxxxxxxxxxxxxxxxxxxxxx/T/#t

Best regards
--
Giulio Benetti
CEO/CTO@Benetti Engineering sas