在 2025/1/9 5:05, David Hildenbrand 写道:
Sorry for the late reply, holidays ...
Did you ever try allocating a larger range with a single
alloc_contig_range() call, that possibly has to migrate multiple hugetlb
folios in one go (and maybe just allocates one of the just-freed hugetlb
folios as migration target)?
I have tried using a single alloc_contig_range() call to allocate a
larger contiguous range, and it works properly. This is because during
the period between __alloc_contig_migrate_range() and
isolate_freepages_range(), no one allocates a hugetlb folio from the
free hugetlb pool.
Did you trigger the following as well?
alloc_contig_range() that covers multiple in-use hugetlb pages, like
[ huge 0 ] [ huge 1 ] [ huge 2 ] [ huge 3 ]
I assume the following happens:
To migrate huge 0, we have to allocate a fresh page from the buddy.
After migration, we return now-free huge 0 to the pool.
To migrate huge 1, we can just grab now-free huge 0 from the pool, and
not allocate a fresh one from the buddy.
At least that's my impression when reading alloc_migration_target()-
>alloc_hugetlb_folio_nodemask().
Thank you very much for your suggestions.
It needs to be discussed in two different scenarios:
1, When All Free HugeTLB Pages in the Pool Are Allocated,
available_huge_page() Returns false
If available_huge_page() returns false, indicating that no free huge
pages are available in the hugeTLB pool, we will invoke
alloc_migrate_hugetlb_folio() to allocate a new folio. A temporary flag
will be set on this new folio. After the migration of the hugeTLB folio
is completed, the temporary flag will be transferred from the new folio
to the old one. Any folio with the temporary flag, when freed, will be
directly released to the buddy allocator.
2, When Some Free HugeTLB Pages in the Pool Are Still Available,
available_huge_page() Returns true
If available_huge_page() returns true, indicating that there are still
free huge pages available in the hugeTLB pool, we will call
dequeue_hugetlb_folio_node() to allocate a new folio. After the
migration of the hugeTLB folio is completed, the old folio will be
released back to the free hugeTLB pool. However, this scenario may pose
potential issues, as you mentioned earlier. It seems that the issue can
be resolved by the following approach:
dequeue_hugetlb_folio_node_exact() {
list_for_each_entry(folio, &h->hugepage_freelists[nid], lru) {
if (is_migrate_isolate_page(folio)) { //determine whether a
hugetlb page is isolated
continue;
}
}
}
Or is for some reason available_huge_pages()==false and we always end up
in alloc_migrate_hugetlb_folio()->alloc_fresh_hugetlb_folio()?
Sorry for the stupid questions, the code is complicated, and I cannot
see how this would work.