mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-18 03:23:53 -04:00
arm64: mm: support batch clearing of the young flag for large folios
Currently, contpte_ptep_test_and_clear_young() and contpte_ptep_clear_flush_young() only clear the young flag and flush TLBs for PTEs within the contiguous range. To support batch PTE operations for other sized large folios in the following patches, adding a new parameter to specify the number of PTEs that map consecutive pages of the same large folio in a single VMA and a single page table. While we are at it, rename the functions to maintain consistency with other contpte_*() functions. Link: https://lkml.kernel.org/r/5644250dcc0417278c266ad37118d27f541fd052.1770645603.git.baolin.wang@linux.alibaba.com Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com> Reviewed-by: Ryan Roberts <ryan.roberts@arm.com> Reviewed-by: David Hildenbrand (Arm) <david@kernel.org> Cc: Barry Song <baohua@kernel.org> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Harry Yoo <harry.yoo@oracle.com> Cc: Jann Horn <jannh@google.com> Cc: Liam Howlett <liam.howlett@oracle.com> Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Rik van Riel <riel@surriel.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Will Deacon <will@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
committed by
Andrew Morton
parent
67d59bddfc
commit
6f0e114217
@@ -1648,10 +1648,10 @@ extern void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
|
||||
extern pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep,
|
||||
unsigned int nr, int full);
|
||||
extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep);
|
||||
extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep);
|
||||
int contpte_test_and_clear_young_ptes(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep, unsigned int nr);
|
||||
int contpte_clear_flush_young_ptes(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep, unsigned int nr);
|
||||
extern void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep, unsigned int nr);
|
||||
extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
|
||||
@@ -1823,7 +1823,7 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
|
||||
if (likely(!pte_valid_cont(orig_pte)))
|
||||
return __ptep_test_and_clear_young(vma, addr, ptep);
|
||||
|
||||
return contpte_ptep_test_and_clear_young(vma, addr, ptep);
|
||||
return contpte_test_and_clear_young_ptes(vma, addr, ptep, 1);
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
|
||||
@@ -1835,7 +1835,7 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
|
||||
if (likely(!pte_valid_cont(orig_pte)))
|
||||
return __ptep_clear_flush_young(vma, addr, ptep);
|
||||
|
||||
return contpte_ptep_clear_flush_young(vma, addr, ptep);
|
||||
return contpte_clear_flush_young_ptes(vma, addr, ptep, 1);
|
||||
}
|
||||
|
||||
#define wrprotect_ptes wrprotect_ptes
|
||||
|
||||
@@ -508,8 +508,9 @@ pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(contpte_get_and_clear_full_ptes);
|
||||
|
||||
int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
int contpte_test_and_clear_young_ptes(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep,
|
||||
unsigned int nr)
|
||||
{
|
||||
/*
|
||||
* ptep_clear_flush_young() technically requires us to clear the access
|
||||
@@ -518,41 +519,45 @@ int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
|
||||
* contig range when the range is covered by a single folio, we can get
|
||||
* away with clearing young for the whole contig range here, so we avoid
|
||||
* having to unfold.
|
||||
*
|
||||
* The 'nr' means consecutive (present) PTEs that map consecutive pages
|
||||
* of the same large folio in a single VMA and a single page table.
|
||||
*/
|
||||
|
||||
unsigned long end = addr + nr * PAGE_SIZE;
|
||||
int young = 0;
|
||||
int i;
|
||||
|
||||
ptep = contpte_align_down(ptep);
|
||||
addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
|
||||
|
||||
for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
|
||||
ptep = contpte_align_addr_ptep(&addr, &end, ptep, nr);
|
||||
for (; addr != end; ptep++, addr += PAGE_SIZE)
|
||||
young |= __ptep_test_and_clear_young(vma, addr, ptep);
|
||||
|
||||
return young;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(contpte_ptep_test_and_clear_young);
|
||||
EXPORT_SYMBOL_GPL(contpte_test_and_clear_young_ptes);
|
||||
|
||||
int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
int contpte_clear_flush_young_ptes(struct vm_area_struct *vma,
|
||||
unsigned long addr, pte_t *ptep,
|
||||
unsigned int nr)
|
||||
{
|
||||
int young;
|
||||
|
||||
young = contpte_ptep_test_and_clear_young(vma, addr, ptep);
|
||||
young = contpte_test_and_clear_young_ptes(vma, addr, ptep, nr);
|
||||
|
||||
if (young) {
|
||||
unsigned long end = addr + nr * PAGE_SIZE;
|
||||
|
||||
contpte_align_addr_ptep(&addr, &end, ptep, nr);
|
||||
/*
|
||||
* See comment in __ptep_clear_flush_young(); same rationale for
|
||||
* eliding the trailing DSB applies here.
|
||||
*/
|
||||
addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
|
||||
__flush_tlb_range_nosync(vma->vm_mm, addr, addr + CONT_PTE_SIZE,
|
||||
__flush_tlb_range_nosync(vma->vm_mm, addr, end,
|
||||
PAGE_SIZE, true, 3);
|
||||
}
|
||||
|
||||
return young;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(contpte_ptep_clear_flush_young);
|
||||
EXPORT_SYMBOL_GPL(contpte_clear_flush_young_ptes);
|
||||
|
||||
void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep, unsigned int nr)
|
||||
|
||||
Reference in New Issue
Block a user