On 3/5/2021 8:40 AM, David Hildenbrand wrote:
The ibft table, for example, is mapped in via acpi_map() and kmap().
The
page for the ibft table is not reserved, so it can end up on the
freelist.
You appear to be saying that it is not sufficient to kmap() a page in
order to use it safely. It is also necessary to reserve it upfront,
for example with the help of memblock_reserve(). Is that correct? If
so, is there an alternative way to reserve a page frame?
If the memory is indicated by the BIOS/firmware as valid memory
(!reserved) but contains actual tables that have to remain untouched
what happens is:
1) Memblock thinks the memory should be given to the buddy, because it
is valid memory and was not reserved by anyone (i.e., the bios, early
allocations).
2) Memblock will expose the pages to the buddy, adding them to the free
page list.
3) Anybody can allocate them, e.g., via alloc_pages().
The root issue is that pages that should not get exposed to the buddy
as free pages get exposed to the buddy as free pages. We have to teach
memblock that these pages are not actually to be used, but instead,
area reserved.
Use memblock_reserve() to reserve all the ACPI table pages.
How is this going to help?
If the ibft table page is not reserved, it will end up on the freelist
and potentially be allocated before ibft_init() is called.
I believe this is the call that causes the ibft table page (in this
case
pfn=0xbe453) to end up on the freelist:
memmap_init_range: size=bd49b, nid=0, zone=1, start_pfn=1000,
zone_end_pfn=100000
David, is commit 7fef431be9c9 related to this and if so, then how?
Memory gets allocated and used in a different order, which seems to
have exposed (yet another) latent BUG. The same could be reproduced
via zone shuffling with a little luck.
Thank you David for the detailed problem description,
George