Page MenuHomeFreeBSD

D15055.id41923.diff
No OneTemporary

D15055.id41923.diff

Index: sys/amd64/amd64/pmap.c
===================================================================
--- sys/amd64/amd64/pmap.c
+++ sys/amd64/amd64/pmap.c
@@ -2261,6 +2261,8 @@
}
}
PMAP_UNLOCK(pmap);
+ if (pa == VM_PAGE_TO_PHYS(zero_page))
+ return (0);
return (pa);
}
@@ -2304,7 +2306,10 @@
&pa))
goto retry;
m = PHYS_TO_VM_PAGE(pte & PG_FRAME);
- vm_page_hold(m);
+ if (m == zero_page)
+ m = NULL;
+ else
+ vm_page_hold(m);
}
}
}
Index: sys/i386/i386/pmap.c
===================================================================
--- sys/i386/i386/pmap.c
+++ sys/i386/i386/pmap.c
@@ -1583,6 +1583,8 @@
}
}
PMAP_UNLOCK(pmap);
+ if (rtval == VM_PAGE_TO_PHYS(zero_page))
+ return (0);
return (rtval);
}
@@ -1626,7 +1628,10 @@
&pa))
goto retry;
m = PHYS_TO_VM_PAGE(pte & PG_FRAME);
- vm_page_hold(m);
+ if (m == zero_page)
+ m = NULL;
+ else
+ vm_page_hold(m);
}
}
}
Index: sys/vm/vm_fault.c
===================================================================
--- sys/vm/vm_fault.c
+++ sys/vm/vm_fault.c
@@ -730,6 +730,36 @@
* page. (Default objects are zero-fill, so there is no real
* pager for them.)
*/
+
+ if (fs.object == fs.first_object && (fs.object->flags &
+ (OBJ_ONEMAPPING | OBJ_NOSPLIT)) == OBJ_ONEMAPPING &&
+ fs.object->shadow_count == 0 &&
+ fs.object->backing_object == NULL &&
+ fault_type == VM_PROT_READ && !wired && m_hold == NULL) {
+ /*
+ * This is a lone nameless anonymous object
+ * not participating in the shadow chains, and
+ * the fault is for read. Install a transient
+ * zero page mapping to avoid allocating real
+ * physical memory until some user content is
+ * written there.
+ *
+ * Write faults allocate and install the real
+ * page. Pmaps must not return zero_page from
+ * pmap_extract() and pmap_extract_and_hold()
+ * for this optimization to work.
+ */
+#ifdef DIAGNOSTIC
+ vm_page_check_zero(zero_page);
+#endif
+ rv = pmap_enter(map->pmap, vaddr, zero_page,
+ VM_PROT_READ, fault_type | PMAP_ENTER_NOSLEEP, 0);
+ if (rv == KERN_SUCCESS) {
+ unlock_and_deallocate(&fs);
+ return (rv);
+ }
+ }
+
if (fs.object->type != OBJT_DEFAULT ||
fs.object == fs.first_object) {
if (fs.pindex >= fs.object->size) {
Index: sys/vm/vm_kern.c
===================================================================
--- sys/vm/vm_kern.c
+++ sys/vm/vm_kern.c
@@ -610,6 +610,8 @@
vm_map_unlock(map);
}
+vm_page_t zero_page;
+
void
kmem_init_zero_region(void)
{
@@ -622,7 +624,7 @@
* zeros, while not using much more physical resources.
*/
addr = kva_alloc(ZERO_REGION_SIZE);
- m = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL |
+ zero_page = m = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL |
VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | VM_ALLOC_ZERO);
if ((m->flags & PG_ZERO) == 0)
pmap_zero_page(m);
Index: sys/vm/vm_page.h
===================================================================
--- sys/vm/vm_page.h
+++ sys/vm/vm_page.h
@@ -424,6 +424,7 @@
extern vm_page_t vm_page_array; /* First resident page in table */
extern long vm_page_array_size; /* number of vm_page_t's */
extern long first_page; /* first physical page number */
+extern vm_page_t zero_page;
#define VM_PAGE_TO_PHYS(entry) ((entry)->phys_addr)
@@ -532,6 +533,7 @@
vm_page_t vm_page_alloc_freelist_domain(int, int, int);
bool vm_page_blacklist_add(vm_paddr_t pa, bool verbose);
void vm_page_change_lock(vm_page_t m, struct mtx **mtx);
+void vm_page_check_zero(vm_page_t m);
vm_page_t vm_page_grab (vm_object_t, vm_pindex_t, int);
int vm_page_grab_pages(vm_object_t object, vm_pindex_t pindex, int allocflags,
vm_page_t *ma, int count);
Index: sys/vm/vm_page.c
===================================================================
--- sys/vm/vm_page.c
+++ sys/vm/vm_page.c
@@ -3406,6 +3406,29 @@
vm_page_enqueue(m, PQ_ACTIVE);
}
+#if defined(DIAGNOSTIC)
+#if defined(PHYS_TO_DMAP)
+void
+vm_page_check_zero(vm_page_t m)
+{
+ uint64_t *p;
+ int i;
+
+ if (!PMAP_HAS_DMAP)
+ return;
+ p = (uint64_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m));
+ for (i = 0; i < PAGE_SIZE / sizeof(uint64_t); i++, p++)
+ KASSERT(*p == 0, ("vm_page_free_prep %p PG_ZERO %d %jx",
+ m, i, (uintmax_t)*p));
+}
+#else /* !PHYS_TO_DMAP */
+void
+vm_page_check_zero(vm_page_t m)
+{
+}
+#endif /* PHYS_TO_DMAP */
+#endif /* DIAGNOSTIC */
+
/*
* vm_page_free_prep:
*
@@ -3420,15 +3443,9 @@
vm_page_free_prep(vm_page_t m)
{
-#if defined(DIAGNOSTIC) && defined(PHYS_TO_DMAP)
- if (PMAP_HAS_DMAP && (m->flags & PG_ZERO) != 0) {
- uint64_t *p;
- int i;
- p = (uint64_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m));
- for (i = 0; i < PAGE_SIZE / sizeof(uint64_t); i++, p++)
- KASSERT(*p == 0, ("vm_page_free_prep %p PG_ZERO %d %jx",
- m, i, (uintmax_t)*p));
- }
+#ifdef DIAGNOSTIC
+ if ((m->flags & PG_ZERO) != 0)
+ vm_page_check_zero(m);
#endif
if ((m->oflags & VPO_UNMANAGED) == 0) {
vm_page_lock_assert(m, MA_OWNED);

File Metadata

Mime Type
text/plain
Expires
Thu, May 21, 11:15 PM (15 m, 27 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33408518
Default Alt Text
D15055.id41923.diff (4 KB)

Event Timeline