[PATCH makedumpfile] Add confidential VM unaccepted free pages support on Linux 6.16 and later

HAGIO KAZUHITO(萩尾 一仁) k-hagio-ab at nec.com
Sun Jun 29 23:24:42 PDT 2025


On 2025/06/30 15:30, Zhiquan Li wrote:
> 
> 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.

Thank you Zhiquan for the detailed explanation, which made me understand 
more clearly.  And the patch looks good to me, so ack.

(There is no need to add my acked-by tag to the patch, we will merge 
this when Masa sends his ack.)

Thanks,
Kazu

> 
> 
> 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