Re: [PATCH v2 1/2] mm: Make alloc_contig_range handle free hugetlb pages
From: Oscar Salvador <osalvador@suse.de>
Date: 2021-02-19 06:09:31
Also in:
lkml
On 2021-02-19 03:10, Mike Kravetz wrote:
Those counts will be wrong as there are no huge pages on the node. I'll think about this more tomorrow. Pretty sure this is an issue, but I could be wrong. Just wanted to give a heads up.
Yes, this is a problem, although the fixup would be to check whether we have any hugepages. Nevertheless, I think we should not be touching surplus at all but rather make the page temporary. I am exploring making migrate_pages() handle free hugepages as Michal suggested, so the approach is cleaner and we do not need extra functions. I yet have to see if that is feasible, as some issues come to my mind like the page needs to be in a list to go to migrate_pages, but if it is in that list, it is not in hugepages_freelist, and that could disrupt userspace as it could not dequeue hugepages if it demands it. I have to check. Shoult not be possible, we can always make the page temporary here.
-- Mike Kravetzquoted
+ } + } + + return ret; +} + +bool isolate_or_dissolve_huge_page(struct page *page) +{ + struct hstate *h = NULL; + struct page *head; + bool ret = false; + + spin_lock(&hugetlb_lock); + if (PageHuge(page)) { + head = compound_head(page); + h = page_hstate(head); + } + spin_unlock(&hugetlb_lock); + + /* + * The page might have been dissolved from under our feet. + * If that is the case, return success as if we dissolved it ourselves. + */ + if (!h) + return true; + + /* + * Fence off gigantic pages as there is a cyclic dependency + * between alloc_contig_range and them. + */ + if (hstate_is_gigantic(h)) + return ret; + + if(!page_count(head) && alloc_and_dissolve_huge_page(h, head)) + ret = true; + + return ret; +} + struct page *alloc_huge_page(struct vm_area_struct *vma, unsigned long addr, int avoid_reserve) {
-- Oscar Salvador SUSE L3