On 10.12.2025 13:44, Oleksii Kurochko wrote:
> On 12/10/25 8:06 AM, Jan Beulich wrote:
>> On 09.12.2025 18:09, Oleksii Kurochko wrote:
>>> On 12/9/25 2:47 PM, Jan Beulich wrote:
>>>> On 24.11.2025 13:33, Oleksii Kurochko wrote:
>>>>> +            *md_pg = p2m_alloc_page(p2m);
>>>>> +            if ( !*md_pg )
>>>>> +            {
>>>>> +                printk("%pd: can't allocate metadata page\n", 
>>>>> p2m->domain);
>>>>> +                domain_crash(p2m->domain);
>>>>> +
>>>>> +                return;
>>>>> +            }
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    if ( *md_pg )
>>>>> +        metadata = __map_domain_page(*md_pg);
>>>>> +
>>>>> +    if ( t >= p2m_first_external )
>>>>> +    {
>>>>> +        metadata[ctx->index].type = t;
>>>>> +
>>>>> +        t = p2m_ext_storage;
>>>>> +    }
>>>>> +    else if ( metadata )
>>>>> +        metadata[ctx->index].type = p2m_invalid;
>>>>> +
>>>>> +    pte->pte |= MASK_INSR(t, P2M_TYPE_PTE_BITS_MASK);
>>>>> +
>>>>> +    unmap_domain_page(metadata);
>>>>>    }
>>>> Just to mention (towards future work): Once a metadata page goes back to be
>>>> entirely zero-filled, it could as well be hooked off and returned to the 
>>>> pool.
>>>> Not doing so may mean detaining an unused page indefinitely.
>>> Won’t that already happen when p2m_free_table() is called?
>> Well, that's when both page table and metadata table are freed. But what if a
>> leaf page table is moving back to holding all p2m_ram_rw mappings? Then the
>> metadata page is unused, but will remain allocated.
> 
> Good point...
> 
> This could be a rather expensive operation, since in the code:
>    +    else if ( metadata )
>    +        metadata[ctx->index].type = p2m_invalid;
> we would have to check all other metadata entries to determine whether they 
> are
> (p2m_invalid) or not, and return the page to the pool.
> 
> It would be nice to have something like metadata.used_entries_num, but the 
> entire
> page is used for type entries.
> As an option, we could reserve 8 bits to store a counter of the number of used
> entries in the metadata page, and then use metadata[0].used_entries_num to 
> check
> whether it is zero. If it is zero, we could simply return the metadata page 
> to the
> pool in the “else if (metadata)” case mentioned above.
> 
> How bad is this idea? Any better suggestions?

First, as said in my initial reply: This may not need taking care of right away.
It will need keeping in mind, of course.

As to suggestions - hardly any of the fields in struct page_info for the page
can be used when the page is a metadata one. Simply record the count there?

Finally, as to "rather expensive": Scanning a 4k page to hold all zeroes can't
be all that expensive? In any event that expensiveness needs weighing carefully
against the risk of getting the counter maintenance wrong.

Jan

Reply via email to