
Offering: HULK hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IBZIRG ------------------------------- If task A had hold the zone->lock before trigger page fault when touch the page which is doing break-before-make by another task, a ABBA deadlock can happen: CPU0 CPU1 ---------------------------------------------------------------- free_pages() got zone->lock touch struct page in BBM __do_kernel_fault() check spurious PF vmemmap_handle_page_fault() split_vmemmap_huge_pmd() got init_mm.page_table_lock pte_free_kernel() want init_mm.page_table_lock want zone->lock <--- DEAD LOCK Fix this by moving pte_free_kernel() out from init_mm.page_table_lock spin lock scope. The probability of encountering this issue should be very low because in most cases, the page table has restored when checking spurious PF. Fixes: 9f779dc0a09c ("arm64: mm: HVO: support BBM of vmemmap pgtable safely") Signed-off-by: Nanyong Sun <sunnanyong@huawei.com> --- mm/hugetlb_vmemmap.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c index 427cfd08069e..2bde429b2ea3 100644 --- a/mm/hugetlb_vmemmap.c +++ b/mm/hugetlb_vmemmap.c @@ -121,11 +121,13 @@ static int split_vmemmap_huge_pmd(pmd_t *pmd, unsigned long start) smp_wmb(); vmemmap_update_pmd(start, pmd, pgtable); vmemmap_flush_tlb_range(start, start + PMD_SIZE); - } else { - pte_free_kernel(&init_mm, pgtable); + pgtable = NULL; } vmemmap_split_unlock(&init_mm.page_table_lock); + if (unlikely(pgtable)) + pte_free_kernel(&init_mm, pgtable); + return 0; } -- 2.34.1