/* We must align the address, because our caller will run *set_huge_pte_at()onwhateverwereturn,whichwritesout *allofthesub-ptesforthehugepagerange.Sowehave *togiveitthefirstsuchsub-pte.
*/
addr &= HPAGE_MASK;
pgd = pgd_offset(mm, addr); if (!pgd_none(*pgd)) {
p4d = p4d_offset(pgd, addr); if (!p4d_none(*p4d)) {
pud = pud_offset(p4d, addr); if (!pud_none(*pud)) {
pmd = pmd_offset(pud, addr); if (!pmd_none(*pmd))
pte = pte_offset_huge(pmd, addr);
}
}
} return pte;
}
/* Purge data and instruction TLB entries. Must be called holding *thepa_tlb_lock.TheTLBpurgeinstructionsareslowonSMP *machinessincethepurgemustbebroadcasttoallCPUs.
*/ staticinlinevoid purge_tlb_entries_huge(struct mm_struct *mm, unsignedlong addr)
{ int i;
/* We may use multiple physical huge pages (e.g. 2x1 MB) to emulate
* Linux standard huge pages (e.g. 2 MB) */
BUILD_BUG_ON(REAL_HPAGE_SHIFT > HPAGE_SHIFT);
for (i = 0; i < (1 << (HPAGE_SHIFT-REAL_HPAGE_SHIFT)); i++) {
purge_tlb_entries(mm, addr);
addr += (1UL << REAL_HPAGE_SHIFT);
}
}
/* __set_huge_pte_at() must be called holding the pa_tlb_lock. */ staticvoid __set_huge_pte_at(struct mm_struct *mm, unsignedlong addr,
pte_t *ptep, pte_t entry)
{ unsignedlong addr_start; int i;
addr &= HPAGE_MASK;
addr_start = addr;
for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
set_pte(ptep, entry);
ptep++;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.