diff options
| -rw-r--r-- | mm/khugepaged.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/mm/khugepaged.c b/mm/khugepaged.c index 6b442f760ce1e..ce69611e2fb26 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -1210,6 +1210,12 @@ static enum scan_result alloc_charge_folio(struct folio **foliop, struct mm_stru return SCAN_SUCCEED; } +/* + * collapse_huge_page expects the mmap_lock to be unlocked before entering and + * will always return with the lock unlocked, to avoid holding the mmap_lock + * while allocating a THP, as that could trigger direct reclaim/compaction. + * Note that the VMA must be rechecked after grabbing the mmap_lock again. + */ static enum scan_result collapse_huge_page(struct mm_struct *mm, unsigned long address, int referenced, int unmapped, struct collapse_control *cc) { @@ -1225,14 +1231,6 @@ static enum scan_result collapse_huge_page(struct mm_struct *mm, unsigned long a VM_BUG_ON(address & ~HPAGE_PMD_MASK); - /* - * Before allocating the hugepage, release the mmap_lock read lock. - * The allocation can take potentially a long time if it involves - * sync compaction, and we do not need to hold the mmap_lock during - * that. We will recheck the vma after taking it again in write mode. - */ - mmap_read_unlock(mm); - result = alloc_charge_folio(&folio, mm, cc, HPAGE_PMD_ORDER); if (result != SCAN_SUCCEED) goto out_nolock; @@ -1537,6 +1535,8 @@ static enum scan_result collapse_scan_pmd(struct mm_struct *mm, out_unmap: pte_unmap_unlock(pte, ptl); if (result == SCAN_SUCCEED) { + /* collapse_huge_page expects the lock to be dropped before calling */ + mmap_read_unlock(mm); result = collapse_huge_page(mm, start_addr, referenced, unmapped, cc); /* collapse_huge_page will return with the mmap_lock released */ |
