Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm: centralize+fix comments about compound_mapcount() in new sync_with_folio_pmd_zap()

We still mention compound_mapcount() in two comments.

Instead of simply referring to the folio mapcount in both places, let's
factor out the odd-looking PTL sync into sync_with_folio_pmd_zap(), and
add centralized documentation why this is required.

[akpm@linux-foundation.org: update comment per Matthew and David]
Link: https://lkml.kernel.org/r/20260223163920.287720-1-david@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Liam Howlett <Liam.Howlett@oracle.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Rik van Riel <riel@surriel.com>
Cc: Harry Yoo <harry.yoo@oracle.com>
Cc: Jann Horn <jannh@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

David Hildenbrand (Arm) and committed by
Andrew Morton
514c2fe9 05620419

+22 -16
+19
mm/internal.h
··· 516 516 517 517 void pmd_install(struct mm_struct *mm, pmd_t *pmd, pgtable_t *pte); 518 518 519 + /** 520 + * sync_with_folio_pmd_zap - sync with concurrent zapping of a folio PMD 521 + * @mm: The mm_struct. 522 + * @pmdp: Pointer to the pmd that was found to be pmd_none(). 523 + * 524 + * When we find a pmd_none() while unmapping a folio without holding the PTL, 525 + * zap_huge_pmd() may have cleared the PMD but not yet modified the folio to 526 + * indicate that it's unmapped. Skipping the PMD without synchronization could 527 + * make folio unmapping code assume that unmapping failed. 528 + * 529 + * Wait for concurrent zapping to complete by grabbing the PTL. 530 + */ 531 + static inline void sync_with_folio_pmd_zap(struct mm_struct *mm, pmd_t *pmdp) 532 + { 533 + spinlock_t *ptl = pmd_lock(mm, pmdp); 534 + 535 + spin_unlock(ptl); 536 + } 537 + 519 538 struct zap_details; 520 539 void unmap_page_range(struct mmu_gather *tlb, 521 540 struct vm_area_struct *vma,
+1 -7
mm/memory.c
··· 1993 1993 } else if (details && details->single_folio && 1994 1994 folio_test_pmd_mappable(details->single_folio) && 1995 1995 next - addr == HPAGE_PMD_SIZE && pmd_none(*pmd)) { 1996 - spinlock_t *ptl = pmd_lock(tlb->mm, pmd); 1997 - /* 1998 - * Take and drop THP pmd lock so that we cannot return 1999 - * prematurely, while zap_huge_pmd() has cleared *pmd, 2000 - * but not yet decremented compound_mapcount(). 2001 - */ 2002 - spin_unlock(ptl); 1996 + sync_with_folio_pmd_zap(tlb->mm, pmd); 2003 1997 } 2004 1998 if (pmd_none(*pmd)) { 2005 1999 addr = next;
+2 -9
mm/page_vma_mapped.c
··· 269 269 spin_unlock(pvmw->ptl); 270 270 pvmw->ptl = NULL; 271 271 } else if (!pmd_present(pmde)) { 272 - /* 273 - * If PVMW_SYNC, take and drop THP pmd lock so that we 274 - * cannot return prematurely, while zap_huge_pmd() has 275 - * cleared *pmd but not decremented compound_mapcount(). 276 - */ 277 272 const softleaf_t entry = softleaf_from_pmd(pmde); 278 273 279 274 if (softleaf_is_device_private(entry)) { ··· 279 284 if ((pvmw->flags & PVMW_SYNC) && 280 285 thp_vma_suitable_order(vma, pvmw->address, 281 286 PMD_ORDER) && 282 - (pvmw->nr_pages >= HPAGE_PMD_NR)) { 283 - spinlock_t *ptl = pmd_lock(mm, pvmw->pmd); 287 + (pvmw->nr_pages >= HPAGE_PMD_NR)) 288 + sync_with_folio_pmd_zap(mm, pvmw->pmd); 284 289 285 - spin_unlock(ptl); 286 - } 287 290 step_forward(pvmw, PMD_SIZE); 288 291 continue; 289 292 }