Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/arm64/pmap.c
Show First 20 Lines • Show All 186 Lines • ▼ Show 20 Lines | ||||||||||||
#define pmap_l0_pindex(v) (NUL2E + NUL1E + ((v) >> L0_SHIFT)) | #define pmap_l0_pindex(v) (NUL2E + NUL1E + ((v) >> L0_SHIFT)) | |||||||||||
#define pmap_l1_pindex(v) (NUL2E + ((v) >> L1_SHIFT)) | #define pmap_l1_pindex(v) (NUL2E + ((v) >> L1_SHIFT)) | |||||||||||
#define pmap_l2_pindex(v) ((v) >> L2_SHIFT) | #define pmap_l2_pindex(v) ((v) >> L2_SHIFT) | |||||||||||
#ifdef NUMA | #ifdef NUMA | |||||||||||
struct pmap_large_md_page { | struct pmap_large_md_page { | |||||||||||
struct rwlock pv_lock; | struct rwlock pv_lock; | |||||||||||
struct md_page pv_page; | struct md_page pv_page; | |||||||||||
/* Pad to a power of 2 */ | /* Pad to a power of 2, see pmap_init_pv_table(). */ | |||||||||||
markjUnsubmitted Done Inline Actions
markj: | ||||||||||||
int pv_pad[2]; | int pv_pad[2]; | |||||||||||
}; | }; | |||||||||||
static struct pmap_large_md_page * | static struct pmap_large_md_page * | |||||||||||
_pa_to_pmdp(vm_paddr_t pa) | _pa_to_pmdp(vm_paddr_t pa) | |||||||||||
{ | { | |||||||||||
struct vm_phys_seg *seg; | struct vm_phys_seg *seg; | |||||||||||
int segind; | int segind; | |||||||||||
▲ Show 20 Lines • Show All 1,174 Lines • ▼ Show 20 Lines | pmap_init_pv_table(void) | |||||||||||
} | } | |||||||||||
s = (vm_size_t)pv_npg * sizeof(struct pmap_large_md_page); | s = (vm_size_t)pv_npg * sizeof(struct pmap_large_md_page); | |||||||||||
s = round_page(s); | s = round_page(s); | |||||||||||
pv_table = (struct pmap_large_md_page *)kva_alloc(s); | pv_table = (struct pmap_large_md_page *)kva_alloc(s); | |||||||||||
if (pv_table == NULL) | if (pv_table == NULL) | |||||||||||
panic("%s: kva_alloc failed\n", __func__); | panic("%s: kva_alloc failed\n", __func__); | |||||||||||
/* | /* | |||||||||||
* Iterate physical segments to allocate space for respective pages. | * Iterate physical segments to allocate domain-local memory for PV | |||||||||||
* list headers. | ||||||||||||
Done Inline Actions
markj: | ||||||||||||
*/ | */ | |||||||||||
highest = -1; | highest = -1; | |||||||||||
s = 0; | s = 0; | |||||||||||
for (i = 0; i < vm_phys_nsegs; i++) { | for (i = 0; i < vm_phys_nsegs; i++) { | |||||||||||
seg = &vm_phys_segs[i]; | seg = &vm_phys_segs[i]; | |||||||||||
start = highest + 1; | start = highest + 1; | |||||||||||
end = start + pmap_l2_pindex(roundup2(seg->end, L2_SIZE)) - | end = start + pmap_l2_pindex(roundup2(seg->end, L2_SIZE)) - | |||||||||||
pmap_l2_pindex(seg->start); | pmap_l2_pindex(seg->start); | |||||||||||
domain = seg->domain; | domain = seg->domain; | |||||||||||
if (highest >= end) | if (highest >= end) | |||||||||||
continue; | continue; | |||||||||||
pvd = &pv_table[start]; | pvd = &pv_table[start]; | |||||||||||
pages = end - start + 1; | pages = end - start + 1; | |||||||||||
s = round_page(pages * sizeof(*pvd)); | s = round_page(pages * sizeof(*pvd)); | |||||||||||
highest = start + (s / sizeof(*pvd)) - 1; | highest = start + (s / sizeof(*pvd)) - 1; | |||||||||||
for (j = 0; j < s; j += PAGE_SIZE) { | for (j = 0; j < s; j += PAGE_SIZE) { | |||||||||||
vm_page_t m = vm_page_alloc_noobj_domain(domain, 0); | vm_page_t m = vm_page_alloc_noobj_domain(domain, | |||||||||||
VM_ALLOC_ZERO); | ||||||||||||
if (m == NULL) | if (m == NULL) | |||||||||||
panic("failed to allocate PV table page"); | panic("failed to allocate PV table page"); | |||||||||||
Done Inline ActionsPass VM_ALLOC_ZERO to vm_page_alloc_noobj_domain() instead of calling pmap_zero_page(). markj: Pass VM_ALLOC_ZERO to vm_page_alloc_noobj_domain() instead of calling pmap_zero_page(). | ||||||||||||
pmap_zero_page(m); | ||||||||||||
pmap_qenter((vm_offset_t)pvd + j, &m, 1); | pmap_qenter((vm_offset_t)pvd + j, &m, 1); | |||||||||||
} | } | |||||||||||
for (j = 0; j < s / sizeof(*pvd); j++) { | for (j = 0; j < s / sizeof(*pvd); j++) { | |||||||||||
rw_init_flags(&pvd->pv_lock, "pmap pv list", RW_NEW); | rw_init_flags(&pvd->pv_lock, "pmap pv list", RW_NEW); | |||||||||||
TAILQ_INIT(&pvd->pv_page.pv_list); | TAILQ_INIT(&pvd->pv_page.pv_list); | |||||||||||
pvd++; | pvd++; | |||||||||||
} | } | |||||||||||
▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | pmap_init(void) | |||||||||||
* Initialize pv chunk lists. | * Initialize pv chunk lists. | |||||||||||
*/ | */ | |||||||||||
for (i = 0; i < PMAP_MEMDOM; i++) { | for (i = 0; i < PMAP_MEMDOM; i++) { | |||||||||||
mtx_init(&pv_chunks[i].pvc_lock, "pmap pv chunk list", NULL, | mtx_init(&pv_chunks[i].pvc_lock, "pmap pv chunk list", NULL, | |||||||||||
MTX_DEF); | MTX_DEF); | |||||||||||
TAILQ_INIT(&pv_chunks[i].pvc_list); | TAILQ_INIT(&pv_chunks[i].pvc_list); | |||||||||||
} | } | |||||||||||
pmap_init_pv_table(); | pmap_init_pv_table(); | |||||||||||
Done Inline ActionsExtra newline. markj: Extra newline. | ||||||||||||
vm_initialized = 1; | vm_initialized = 1; | |||||||||||
} | } | |||||||||||
static SYSCTL_NODE(_vm_pmap, OID_AUTO, l2, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, | static SYSCTL_NODE(_vm_pmap, OID_AUTO, l2, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, | |||||||||||
"2MB page mapping counters"); | "2MB page mapping counters"); | |||||||||||
static u_long pmap_l2_demotions; | static u_long pmap_l2_demotions; | |||||||||||
SYSCTL_ULONG(_vm_pmap_l2, OID_AUTO, demotions, CTLFLAG_RD, | SYSCTL_ULONG(_vm_pmap_l2, OID_AUTO, demotions, CTLFLAG_RD, | |||||||||||
▲ Show 20 Lines • Show All 6,240 Lines • Show Last 20 Lines |