svn commit: r334233 - head/sys/vm
Alan Cox
alc at FreeBSD.org
Sat May 26 02:59:35 UTC 2018
Author: alc
Date: Sat May 26 02:59:34 2018
New Revision: 334233
URL: https://svnweb.freebsd.org/changeset/base/334233
Log:
Use pmap_enter(..., psind=1) in vm_fault_populate() on amd64. While
superpage mappings were already being created by automatic promotion in
vm_fault_populate(), this change reduces the cost of creating those
mappings. Essentially, one pmap_enter(..., psind=1) call takes the place
of 512 pmap_enter(..., psind=0) calls, and that one pmap_enter(...,
psind=1) call eliminates the allocation of a page table page.
Reviewed by: kib
MFC after: 10 days
Differential Revision: https://reviews.freebsd.org/D15572
Modified:
head/sys/vm/vm_fault.c
Modified: head/sys/vm/vm_fault.c
==============================================================================
--- head/sys/vm/vm_fault.c Sat May 26 02:45:41 2018 (r334232)
+++ head/sys/vm/vm_fault.c Sat May 26 02:59:34 2018 (r334233)
@@ -380,9 +380,11 @@ static int
vm_fault_populate(struct faultstate *fs, vm_prot_t prot, int fault_type,
int fault_flags, boolean_t wired, vm_page_t *m_hold)
{
+ struct mtx *m_mtx;
+ vm_offset_t vaddr;
vm_page_t m;
vm_pindex_t map_first, map_last, pager_first, pager_last, pidx;
- int rv;
+ int i, npages, psind, rv;
MPASS(fs->object == fs->first_object);
VM_OBJECT_ASSERT_WLOCKED(fs->first_object);
@@ -455,26 +457,44 @@ vm_fault_populate(struct faultstate *fs, vm_prot_t pro
pager_last = map_last;
}
for (pidx = pager_first, m = vm_page_lookup(fs->first_object, pidx);
- pidx <= pager_last; pidx++, m = vm_page_next(m)) {
- vm_fault_populate_check_page(m);
- vm_fault_dirty(fs->entry, m, prot, fault_type, fault_flags,
- true);
+ pidx <= pager_last;
+ pidx += npages, m = vm_page_next(&m[npages - 1])) {
+ vaddr = fs->entry->start + IDX_TO_OFF(pidx) - fs->entry->offset;
+#if defined(__amd64__)
+ psind = m->psind;
+ if (psind > 0 && ((vaddr & (pagesizes[psind] - 1)) != 0 ||
+ pidx + OFF_TO_IDX(pagesizes[psind]) - 1 > pager_last ||
+ !pmap_ps_enabled(fs->map->pmap)))
+ psind = 0;
+#else
+ psind = 0;
+#endif
+ npages = atop(pagesizes[psind]);
+ for (i = 0; i < npages; i++) {
+ vm_fault_populate_check_page(&m[i]);
+ vm_fault_dirty(fs->entry, &m[i], prot, fault_type,
+ fault_flags, true);
+ }
VM_OBJECT_WUNLOCK(fs->first_object);
- pmap_enter(fs->map->pmap, fs->entry->start + IDX_TO_OFF(pidx) -
- fs->entry->offset, m, prot, fault_type | (wired ?
- PMAP_ENTER_WIRED : 0), 0);
+ pmap_enter(fs->map->pmap, vaddr, m, prot, fault_type | (wired ?
+ PMAP_ENTER_WIRED : 0), psind);
VM_OBJECT_WLOCK(fs->first_object);
- if (pidx == fs->first_pindex)
- vm_fault_fill_hold(m_hold, m);
- vm_page_lock(m);
- if ((fault_flags & VM_FAULT_WIRE) != 0) {
- KASSERT(wired, ("VM_FAULT_WIRE && !wired"));
- vm_page_wire(m);
- } else {
- vm_page_activate(m);
+ m_mtx = NULL;
+ for (i = 0; i < npages; i++) {
+ vm_page_change_lock(&m[i], &m_mtx);
+ if ((fault_flags & VM_FAULT_WIRE) != 0) {
+ KASSERT(wired, ("VM_FAULT_WIRE && !wired"));
+ vm_page_wire(&m[i]);
+ } else
+ vm_page_activate(&m[i]);
+ if (m_hold != NULL && m[i].pindex == fs->first_pindex) {
+ *m_hold = &m[i];
+ vm_page_hold(&m[i]);
+ }
+ vm_page_xunbusy(&m[i]);
}
- vm_page_unlock(m);
- vm_page_xunbusy(m);
+ if (m_mtx != NULL)
+ mtx_unlock(m_mtx);
}
curthread->td_ru.ru_majflt++;
return (KERN_SUCCESS);
More information about the svn-src-head
mailing list