On 1/10/21 4:40 AM, 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.
Fixes: c8721bbbdd36 ("mm: memory-hotplug: enable memory hotplug to handle hugepage") Signed-off-by: Muchun Song songmuchun@bytedance.com Cc: stable@vger.kernel.org
mm/hugetlb.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
Thanks,
It is unfortunate that we have to add more huge page state information to fix this issue. However, I believe we have explored all other options.
Reviewed-by: Mike Kravetz mike.kravetz@oracle.com