arch/arm64/mm/contpte.c
Source file repositories/reference/linux-study-clean/arch/arm64/mm/contpte.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm64/mm/contpte.c- Extension
.c- Size
- 21884 bytes
- Lines
- 699
- Domain
- Architecture Layer
- Bucket
- arch/arm64
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/mm.hlinux/efi.hlinux/export.hasm/tlbflush.h
Detected Declarations
function Copyrightfunction contpte_try_unfold_partialfunction contpte_convertfunction __contpte_try_foldfunction __contpte_try_unfoldfunction contpte_ptep_getfunction contpte_is_consistentfunction contpte_ptep_get_locklessfunction contpte_set_ptesfunction contpte_clear_full_ptesfunction contpte_get_and_clear_full_ptesfunction contpte_test_and_clear_young_ptesfunction contpte_clear_flush_young_ptesfunction contpte_wrprotect_ptesfunction contpte_clear_young_dirty_ptesfunction contpte_all_subptes_match_access_flagsfunction contpte_ptep_set_access_flagsexport __contpte_try_foldexport __contpte_try_unfoldexport contpte_ptep_getexport contpte_ptep_get_locklessexport contpte_set_ptesexport contpte_clear_full_ptesexport contpte_get_and_clear_full_ptesexport contpte_test_and_clear_young_ptesexport contpte_clear_flush_young_ptesexport contpte_wrprotect_ptesexport contpte_clear_young_dirty_ptesexport contpte_ptep_set_access_flags
Annotated Snippet
if (pte_dirty(pte)) {
orig_pte = pte_mkdirty(orig_pte);
for (; i < CONT_PTES; i++, ptep++) {
pte = __ptep_get(ptep);
if (pte_young(pte)) {
orig_pte = pte_mkyoung(orig_pte);
break;
}
}
break;
}
if (pte_young(pte)) {
orig_pte = pte_mkyoung(orig_pte);
i++;
ptep++;
for (; i < CONT_PTES; i++, ptep++) {
pte = __ptep_get(ptep);
if (pte_dirty(pte)) {
orig_pte = pte_mkdirty(orig_pte);
break;
}
}
break;
}
}
return orig_pte;
}
EXPORT_SYMBOL_GPL(contpte_ptep_get);
static inline bool contpte_is_consistent(pte_t pte, unsigned long pfn,
pgprot_t orig_prot)
{
pgprot_t prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
return pte_valid_cont(pte) && pte_pfn(pte) == pfn &&
pgprot_val(prot) == pgprot_val(orig_prot);
}
pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
{
/*
* The ptep_get_lockless() API requires us to read and return *orig_ptep
* so that it is self-consistent, without the PTL held, so we may be
* racing with other threads modifying the pte. Usually a READ_ONCE()
* would suffice, but for the contpte case, we also need to gather the
* access and dirty bits from across all ptes in the contiguous block,
* and we can't read all of those neighbouring ptes atomically, so any
* contiguous range may be unfolded/modified/refolded under our feet.
* Therefore we ensure we read a _consistent_ contpte range by checking
* that all ptes in the range are valid and have CONT_PTE set, that all
* pfns are contiguous and that all pgprots are the same (ignoring
* access/dirty). If we find a pte that is not consistent, then we must
* be racing with an update so start again. If the target pte does not
* have CONT_PTE set then that is considered consistent on its own
* because it is not part of a contpte range.
*/
pgprot_t orig_prot;
unsigned long pfn;
pte_t orig_pte;
pte_t *ptep;
pte_t pte;
int i;
retry:
orig_pte = __ptep_get(orig_ptep);
if (!pte_valid_cont(orig_pte))
return orig_pte;
orig_prot = pte_pgprot(pte_mkold(pte_mkclean(orig_pte)));
ptep = contpte_align_down(orig_ptep);
pfn = pte_pfn(orig_pte) - (orig_ptep - ptep);
for (i = 0; i < CONT_PTES; i++, ptep++, pfn++) {
pte = __ptep_get(ptep);
if (!contpte_is_consistent(pte, pfn, orig_prot))
goto retry;
if (pte_dirty(pte)) {
orig_pte = pte_mkdirty(orig_pte);
for (; i < CONT_PTES; i++, ptep++, pfn++) {
pte = __ptep_get(ptep);
if (!contpte_is_consistent(pte, pfn, orig_prot))
goto retry;
Annotation
- Immediate include surface: `linux/mm.h`, `linux/efi.h`, `linux/export.h`, `asm/tlbflush.h`.
- Detected declarations: `function Copyright`, `function contpte_try_unfold_partial`, `function contpte_convert`, `function __contpte_try_fold`, `function __contpte_try_unfold`, `function contpte_ptep_get`, `function contpte_is_consistent`, `function contpte_ptep_get_lockless`, `function contpte_set_ptes`, `function contpte_clear_full_ptes`.
- Atlas domain: Architecture Layer / arch/arm64.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.