On Mon, Apr 05, 2021 at 04:00:39PM -0700, Mike Kravetz wrote:
> +static void remove_hugetlb_page(struct hstate *h, struct page *page,
> +                                                     bool adjust_surplus)
> +{
> +     int nid = page_to_nid(page);
> +
> +     if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported())
> +             return;
> +
> +     list_del(&page->lru);
> +
> +     if (HPageFreed(page)) {
> +             h->free_huge_pages--;
> +             h->free_huge_pages_node[nid]--;
> +             ClearHPageFreed(page);
> +     }
> +     if (adjust_surplus) {
> +             h->surplus_huge_pages--;
> +             h->surplus_huge_pages_node[nid]--;
> +     }
> +
> +     VM_BUG_ON_PAGE(hugetlb_cgroup_from_page(page), page);
> +     VM_BUG_ON_PAGE(hugetlb_cgroup_from_page_rsvd(page), page);

These checks feel a bit odd here.
I would move them above, before we start messing with the counters?

> +
> +     ClearHPageTemporary(page);

Why clearing it unconditionally? I guess we do not really care, but
someone might wonder why when reading the core.
So I would either do as we used to do and only clear it in case of
HPageTemporary(), or drop a comment.

> +     set_page_refcounted(page);
> +     set_compound_page_dtor(page, NULL_COMPOUND_DTOR);
> +
> +     h->nr_huge_pages--;
> +     h->nr_huge_pages_node[nid]--;
> +}

As Michal pointed out, remove_hugetlb_page() from
alloc_and_dissolve_huge_page() might be problematic in some cases because
the new_page has not been enqueued yet.

Now, I guess this might be easily fixed with checking list_empty()
before going ahead with list_del() call, or with another bool parameter
'delete', with a fat comment explaining why we can get to call 
remove_huge_page()
on a page that is not in any list.

Another solution that comes to my mind is to split remove_huge_page() 
functionality in
1) delete from list + unaccount free and surplus pages and 2) reset page's 
state + unaccount
nr_huge_pages

But that might be just biased as would fit for my usecase.
So maybe a list_empty() or the bool parameter might just do.
 

-- 
Oscar Salvador
SUSE L3

Reply via email to