[PATCH makedumpfile] Add confidential VM unaccepted free pages support on Linux 6.16 and later
Zhiquan Li
zhiquan1.li at intel.com
Sun Jun 29 23:30:30 PDT 2025
On 2025/6/30 12:05, HAGIO KAZUHITO(萩尾 一仁) wrote:
> Hi,
>
> thank you for the patch, and sorry for the long delay..
>
Thanks for your time to review this patch. There is a lot of background
knowledge behind this feature, it really needs a long time to digest them.
>> @@ -6630,6 +6633,17 @@ check_order:
>> nr_pages = 1 << private;
>> pfn_counter = &pfn_free;
>> }
>> + /*
>> + * Exclude the unaccepted free pages not managed by buddy.
>> + * By convention, pages can be added to the zone.unaccepted_pages list
>> + * only when the order is MAX_ORDER_NR_PAGES. Otherwise, the page is
>> + * accepted immediately without being on the list.
>> + */
>> + else if ((info->dump_level & DL_EXCLUDE_FREE)
>> + && isUnaccepted(_mapcount)) {
>
>> + nr_pages = 1 << (ARRAY_LENGTH(zone.free_area) - 1);
>
> just to clarify, does this mean that the order of unaccepted pages is
> MAX_PAGE_ORDER but it's not set in struct page, so we need to set the
> order here?
>
Yes, the unit of operations on the buddy system for unaccepted pages is
MAX_PAGE_ORDER, and the type PGTY_unaccepted is only applied on the
first of struct page, not each struct page of MAX_PAGE_ORDER unaccepted
pages need the type. Therefore, if we see one struct page with the
PGTY_unaccepted type, that means the next MAX_PAGE_ORDER-1 unaccepted
pages are added to zone.unaccepted_pages list.
The corresponding kernel code snippets are here:
1. the condition to add unaccepted pages to zone->unaccepted_pages list:
1428 void __meminit __free_pages_core(struct page *page, unsigned int order,
1429 enum meminit_context context)
1430 {
...
1462 if (page_contains_unaccepted(page, order)) {
1463 if (order == MAX_PAGE_ORDER && __free_unaccepted(page))
1464 return;
1465
1466 accept_memory(page_to_phys(page), PAGE_SIZE << order);
1467 }
...
1474 }
At L1463. only when the order is MAX_PAGE_ORDER, the first page is added
zone->unaccepted_pages list, otherwise, accept the unaligned pages
(whose order is not MAX_PAGE_ORDER) immediately. As the unit is always
MAX_PAGE_ORDER (Condition 1), it's not necessary to set PGTY_unaccepted
one by one for each struct page.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/page_alloc.c?h=v6.16-rc4#n1463
2. the operation to append unaccepted pages to zone->unaccepted_pages list:
7278 static bool __free_unaccepted(struct page *page)
7279 {
7280 struct zone *zone = page_zone(page);
...
7287 list_add_tail(&page->lru, &zone->unaccepted_pages);
7288 account_freepages(zone, MAX_ORDER_NR_PAGES, MIGRATE_MOVABLE);
7289 __mod_zone_page_state(zone, NR_UNACCEPTED, MAX_ORDER_NR_PAGES);
7290 __SetPageUnaccepted(page);
...
7294 }
As you can see, the linked list append operation and set PGTY_unaccepted
is only applied on the first page. But the number of account and
statistic is MAX_ORDER_NR_PAGES.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/page_alloc.c?h=v6.16-rc4#n7278
3. the operation to move unaccepted pages from zone->unaccepted_pages
list to buddy system:
7191 static void __accept_page(struct zone *zone, unsigned long *flags,
7192 struct page *page)
7193 {
7194 list_del(&page->lru);
7195 account_freepages(zone, -MAX_ORDER_NR_PAGES, MIGRATE_MOVABLE);
7196 __mod_zone_page_state(zone, NR_UNACCEPTED, -MAX_ORDER_NR_PAGES);
7197 __ClearPageUnaccepted(page);
...
7200 accept_memory(page_to_phys(page), PAGE_SIZE << MAX_PAGE_ORDER);
7201
7202 __free_pages_ok(page, MAX_PAGE_ORDER, FPI_TO_TAIL);
7203 }
As you can see, the linked list remove operation and clear
PGTY_unaccepted is only applied on the first page. And the unit of
account and statistic is still MAX_ORDER_NR_PAGES.
Then accept the pages in size PAGE_SIZE << MAX_PAGE_ORDER at L7200 and
add the MAX_PAGE_ORDER pages to buddy system.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/page_alloc.c?h=v6.16-rc4#n7191
The consideration for Linux kernel is the overhead of switching
operation from SEAM non-root mode -> SEAM root mode while accept page is
big, so it accepted as many pages as possible at a time. If
makedumpfile can be aware of this feature, it can save a lot of disk
space and dump time.
Best Regards,
Zhiquan
More information about the kexec
mailing list