Re: [repost PATCH v2] x86/mm/ident_map: Use gbpages only where full GB page should be mapped.

From: Dave Hansen
Date: Wed Jan 24 2024 - 18:24:22 EST


On 1/24/24 09:36, Steve Wahl wrote:
> Instead of using gbpages for all memory regions, which can include
> vast areas outside what's actually been requested, use them only when
> map creation requests include the full GB page of space; descend to
> using smaller 2M pages when only portions of a GB page are included in
> the request.

This kinda jumps immediately to the solution without stating the problem.

The problem is something like this:

Right now, ident_pud_init() will use 1GB pages to map an area as
long as 1G pages are supported. It does not consider the size
of the area being mapped. Mapping 1G? Use a 1GB mapping.
Mapping 4k? Also use a 1GB mapping. On UV systems, this ends
up mapping BIOS-reserved regions that will cause hardware to
halt the system if accessed, even speculatively.

Right?

> + /*
> + * To be eligible to use a gbpage:
> + * - gbpages must be enabled
> + * - addr must be gb aligned (start of region)
> + * - next must be gb aligned (end of region)
> + * - PUD must be empty (nothing already mapped in this region)
> + */

.. this also needs to say _why_. As it stands, it kinda just rewrites
the code in English which isn't super helpful. It's also awfully
awkward to write a multi-line comment above a multi-line if().

Why not refactor it to do something like:

bool can_use_gbpages = info->direct_gbpages;

/* Avoid using a gbpage when it would be too large: */
can_use_gbpages &= (addr & ~PUD_MASK) ||
(next & ~PUD_MASK);

/* Never overwrite existing mappings: */
can_use_gbpages &= !pud_present(*pud);

if (can_use_gbpages) {
...