On Fri, Jan 15, 2021 at 08:49:40PM +0800, Muchun Song wrote: > There is a race condition between __free_huge_page() > and dissolve_free_huge_page(). > > CPU0: CPU1: > > // page_count(page) == 1 > put_page(page) > __free_huge_page(page) > dissolve_free_huge_page(page) > spin_lock(&hugetlb_lock) > // PageHuge(page) && !page_count(page) > update_and_free_page(page) > // page is freed to the buddy > spin_unlock(&hugetlb_lock) > spin_lock(&hugetlb_lock) > clear_page_huge_active(page) > enqueue_huge_page(page) > // It is wrong, the page is already freed > spin_unlock(&hugetlb_lock) > > The race windows is between put_page() and dissolve_free_huge_page(). > > We should make sure that the page is already on the free list > when it is dissolved. > > As a result __free_huge_page would corrupt page(s) already in the buddy > allocator. > > Fixes: c8721bbbdd36 ("mm: memory-hotplug: enable memory hotplug to handle hugepage") > Signed-off-by: Muchun Song <songmuchun@xxxxxxxxxxxxx> > Reviewed-by: Mike Kravetz <mike.kravetz@xxxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx LGTM, Reviewed-by: Oscar Salvador <osalvador@xxxxxxx> -- Oscar Salvador SUSE L3