}
if ((ptdpg->flags & PG_ZERO) == 0)
bzero(pmap->pm_pml4, PAGE_SIZE);
+#ifdef PMAP_DEBUG
+ else
+ pmap_page_assertzero(VM_PAGE_TO_PHYS(ptdpg));
+#endif
pmap->pm_pml4[KPML4I] = KPDPphys | PG_RW | PG_V | PG_U;
pmap->pm_pml4[DMPML4I] = DMPDPphys | PG_RW | PG_V | PG_U;
if ((m->flags & PG_ZERO) == 0) {
pmap_zero_page(VM_PAGE_TO_PHYS(m));
}
+#ifdef PMAP_DEBUG
+ else {
+ pmap_page_assertzero(VM_PAGE_TO_PHYS(m));
+ }
+#endif
KASSERT(m->queue == PQ_NONE,
("_pmap_allocpte: %p->queue != PQ_NONE", m));
m->hold_count++;
if (m->wire_count++ == 0)
vmstats.v_wire_count++;
+ m->valid = VM_PAGE_BITS_ALL;
+ vm_page_flag_clear(m, PG_ZERO);
/*
* Map the pagetable page into the process address space, if
pmap->pm_ptphint = m;
++pmap->pm_stats.resident_count;
+#if 0
m->valid = VM_PAGE_BITS_ALL;
vm_page_flag_clear(m, PG_ZERO);
+#endif
vm_page_flag_set(m, PG_MAPPED);
vm_page_wakeup(m);
void
pmap_page_assertzero(vm_paddr_t phys)
{
- vm_offset_t virt = PHYS_TO_DMAP(phys);
- int i;
+ vm_offset_t va = PHYS_TO_DMAP(phys);
+ size_t i;
for (i = 0; i < PAGE_SIZE; i += sizeof(long)) {
- if (*(long *)((char *)virt + i) != 0) {
- panic("pmap_page_assertzero() @ %p not zero!\n", (void *)virt);
- }
+ if (*(long *)((char *)va + i) != 0) {
+ panic("pmap_page_assertzero() @ %p not zero!\n",
+ (void *)(intptr_t)va);
+ }
}
}
}
/*
- * See if page is resident. spl protection is required
- * to avoid an interrupt unbusy/free race against our
- * lookup. We must hold the protection through a page
- * allocation or busy.
+ * See if the page is resident.
*/
- crit_enter();
fs->m = vm_page_lookup(fs->object, pindex);
if (fs->m != NULL) {
int queue;
vm_object_deallocate(fs->first_object);
fs->first_object = NULL;
lwkt_reltoken(&vm_token);
- crit_exit();
return (KERN_TRY_AGAIN);
}
unlock_and_deallocate(fs);
vm_waitpfault();
lwkt_reltoken(&vm_token);
- crit_exit();
return (KERN_TRY_AGAIN);
}
* page busy.
*/
vm_page_busy(fs->m);
- crit_exit();
if (fs->m->object != &kernel_object) {
if ((fs->m->valid & VM_PAGE_BITS_ALL) !=
/*
* Page is not resident, If this is the search termination
* or the pager might contain the page, allocate a new page.
- *
- * NOTE: We are still in a critical section.
*/
if (TRYPAGER(fs) || fs->object == fs->first_object) {
/*
*/
if (pindex >= fs->object->size) {
lwkt_reltoken(&vm_token);
- crit_exit();
unlock_and_deallocate(fs);
return (KERN_PROTECTION_FAILURE);
}
limticks = vm_fault_ratelimit(curproc->p_vmspace);
if (limticks) {
lwkt_reltoken(&vm_token);
- crit_exit();
unlock_and_deallocate(fs);
tsleep(curproc, 0, "vmrate", limticks);
fs->didlimit = 1;
}
if (fs->m == NULL) {
lwkt_reltoken(&vm_token);
- crit_exit();
unlock_and_deallocate(fs);
vm_waitpfault();
return (KERN_TRY_AGAIN);
}
}
- crit_exit();
readrest:
/*
scan_count = 16;
}
- crit_enter();
while (scan_count) {
vm_page_t mt;
--scan_count;
--scan_pindex;
}
- crit_exit();
seqaccess = 1;
}
if ((fs->m->flags & PG_ZERO) == 0) {
vm_page_zero_fill(fs->m);
} else {
+#ifdef PMAP_DEBUG
+ pmap_page_assertzero(VM_PAGE_TO_PHYS(fs->m));
+#endif
+ vm_page_flag_clear(fs->m, PG_ZERO);
mycpu->gd_cnt.v_ozfod++;
}
mycpu->gd_cnt.v_zfod++;
vm_object_set_writeable_dirty(fs->m->object);
vm_set_nosync(fs->m, fs->entry);
if (fs->fault_flags & VM_FAULT_DIRTY) {
- crit_enter();
vm_page_dirty(fs->m);
swap_pager_unswapped(fs->m);
- crit_exit();
}
}
* memory.)
*/
src_m = vm_page_lookup(src_object,
- OFF_TO_IDX(dst_offset + src_offset));
+ OFF_TO_IDX(dst_offset + src_offset));
if (src_m == NULL)
panic("vm_fault_copy_wired: page missing");
startpindex = pindex - rbehind;
}
- crit_enter();
lwkt_gettoken(&vm_token);
for (tpindex = pindex; tpindex > startpindex; --tpindex) {
if (vm_page_lookup(object, tpindex - 1))
rtm = vm_page_alloc(object, tpindex, VM_ALLOC_SYSTEM);
if (rtm == NULL) {
lwkt_reltoken(&vm_token);
- crit_exit();
for (j = 0; j < i; j++) {
vm_page_free(marray[j]);
}
++tpindex;
}
lwkt_reltoken(&vm_token);
- crit_exit();
} else {
i = 0;
}
if (endpindex > object->size)
endpindex = object->size;
- crit_enter();
lwkt_gettoken(&vm_token);
while (tpindex < endpindex) {
if (vm_page_lookup(object, tpindex))
++tpindex;
}
lwkt_reltoken(&vm_token);
- crit_exit();
return (i);
}
else if (starta > addra)
starta = 0;
- /*
- * critical section protection is required to maintain the
- * page/object association, interrupts can free pages and remove
- * them from their objects.
- */
- crit_enter();
lwkt_gettoken(&vm_token);
for (i = 0; i < PAGEORDER_SIZE; i++) {
vm_object_t lobject;
if ((m->flags & PG_ZERO) == 0) {
vm_page_zero_fill(m);
} else {
+#ifdef PMAP_DEBUG
+ pmap_page_assertzero(VM_PAGE_TO_PHYS(m));
+#endif
vm_page_flag_clear(m, PG_ZERO);
mycpu->gd_cnt.v_ozfod++;
}
}
}
lwkt_reltoken(&vm_token);
- crit_exit();
}
static volatile int vm_pages_waiting;
-#define ASSERT_IN_CRIT_SECTION() KKASSERT(crit_test(curthread));
-
RB_GENERATE2(vm_page_rb_tree, vm_page, rb_entry, rb_vm_page_compare,
vm_pindex_t, pindex);
void
vm_page_insert(vm_page_t m, vm_object_t object, vm_pindex_t pindex)
{
- ASSERT_IN_CRIT_SECTION();
ASSERT_LWKT_TOKEN_HELD(&vm_token);
if (m->object != NULL)
panic("vm_page_insert: already inserted");
{
vm_object_t object;
- crit_enter();
lwkt_gettoken(&vm_token);
if (m->object == NULL) {
lwkt_reltoken(&vm_token);
- crit_exit();
return;
}
m->object = NULL;
lwkt_reltoken(&vm_token);
- crit_exit();
}
/*
* Search the hash table for this object/offset pair
*/
ASSERT_LWKT_TOKEN_HELD(&vm_token);
- crit_enter();
m = vm_page_rb_tree_RB_LOOKUP(&object->rb_memq, pindex);
- crit_exit();
KKASSERT(m == NULL || (m->object == object && m->pindex == pindex));
return(m);
}
void
vm_page_rename(vm_page_t m, vm_object_t new_object, vm_pindex_t new_pindex)
{
- crit_enter();
lwkt_gettoken(&vm_token);
vm_page_remove(m);
vm_page_insert(m, new_object, new_pindex);
vm_page_dirty(m);
vm_page_wakeup(m);
lwkt_reltoken(&vm_token);
- crit_exit();
}
/*
{
vm_page_t m = NULL;
- crit_enter();
lwkt_gettoken(&vm_token);
KKASSERT(object != NULL);
* On failure return NULL
*/
lwkt_reltoken(&vm_token);
- crit_exit();
#if defined(DIAGNOSTIC)
if (vmstats.v_cache_count > 0)
kprintf("vm_page_alloc(NORMAL): missing pages on cache queue: %d\n", vmstats.v_cache_count);
* No pages available, wakeup the pageout daemon and give up.
*/
lwkt_reltoken(&vm_token);
- crit_exit();
vm_pageout_deficit++;
pagedaemon_wakeup();
return (NULL);
m->valid = 0;
/*
- * vm_page_insert() is safe prior to the crit_exit(). Note also that
+ * vm_page_insert() is safe while holding vm_token. Note also that
* inserting a page here does not insert it into the pmap (which
* could cause us to block allocating memory). We cannot block
* anywhere.
pagedaemon_wakeup();
lwkt_reltoken(&vm_token);
- crit_exit();
/*
* A PG_BUSY page is returned.
void
vm_page_activate(vm_page_t m)
{
- crit_enter();
lwkt_gettoken(&vm_token);
if (m->queue != PQ_ACTIVE) {
if ((m->queue - m->pc) == PQ_CACHE)
m->act_count = ACT_INIT;
}
lwkt_reltoken(&vm_token);
- crit_exit();
}
/*
{
struct vpgqueues *pq;
- crit_enter();
lwkt_gettoken(&vm_token);
mycpu->gd_cnt.v_tfree++;
if ((m->flags & PG_FICTITIOUS) != 0) {
vm_page_wakeup(m);
lwkt_reltoken(&vm_token);
- crit_exit();
return;
}
vm_page_wakeup(m);
vm_page_free_wakeup();
lwkt_reltoken(&vm_token);
- crit_exit();
}
/*
vm_page_t m;
int i;
- crit_enter();
lwkt_gettoken(&vm_token);
for (i = 0; i < PQ_L2_SIZE; ++i) {
m = vm_page_list_find(PQ_FREE, qi, FALSE);
qi = (qi + PQ_PRIME2) & PQ_L2_MASK;
if (m && (m->flags & PG_ZERO) == 0) {
+ KKASSERT(m->busy == 0 && (m->flags & PG_BUSY) == 0);
vm_page_unqueue_nowakeup(m);
vm_page_busy(m);
break;
m = NULL;
}
lwkt_reltoken(&vm_token);
- crit_exit();
return (m);
}
void
vm_page_unmanage(vm_page_t m)
{
- ASSERT_IN_CRIT_SECTION();
ASSERT_LWKT_TOKEN_HELD(&vm_token);
if ((m->flags & PG_UNMANAGED) == 0) {
if (m->wire_count == 0)
* it is already off the queues). Don't do anything with fictitious
* pages because they are always wired.
*/
- crit_enter();
lwkt_gettoken(&vm_token);
if ((m->flags & PG_FICTITIOUS) == 0) {
if (m->wire_count == 0) {
("vm_page_wire: wire_count overflow m=%p", m));
}
lwkt_reltoken(&vm_token);
- crit_exit();
}
/*
void
vm_page_unwire(vm_page_t m, int activate)
{
- crit_enter();
lwkt_gettoken(&vm_token);
if (m->flags & PG_FICTITIOUS) {
/* do nothing */
}
}
lwkt_reltoken(&vm_token);
- crit_exit();
}
void
vm_page_deactivate(vm_page_t m)
{
- crit_enter();
lwkt_gettoken(&vm_token);
_vm_page_deactivate(m, 0);
lwkt_reltoken(&vm_token);
- crit_exit();
}
/*
int
vm_page_try_to_cache(vm_page_t m)
{
- crit_enter();
lwkt_gettoken(&vm_token);
if (m->dirty || m->hold_count || m->busy || m->wire_count ||
(m->flags & (PG_BUSY|PG_UNMANAGED))) {
lwkt_reltoken(&vm_token);
- crit_exit();
return(0);
}
vm_page_test_dirty(m);
if (m->dirty) {
lwkt_reltoken(&vm_token);
- crit_exit();
return(0);
}
vm_page_cache(m);
lwkt_reltoken(&vm_token);
- crit_exit();
return(1);
}
int
vm_page_try_to_free(vm_page_t m)
{
- crit_enter();
lwkt_gettoken(&vm_token);
if (m->dirty || m->hold_count || m->busy || m->wire_count ||
(m->flags & (PG_BUSY|PG_UNMANAGED))) {
lwkt_reltoken(&vm_token);
- crit_exit();
return(0);
}
vm_page_test_dirty(m);
if (m->dirty) {
lwkt_reltoken(&vm_token);
- crit_exit();
return(0);
}
vm_page_busy(m);
vm_page_protect(m, VM_PROT_NONE);
vm_page_free(m);
lwkt_reltoken(&vm_token);
- crit_exit();
return(1);
}
void
vm_page_cache(vm_page_t m)
{
- ASSERT_IN_CRIT_SECTION();
ASSERT_LWKT_TOKEN_HELD(&vm_token);
if ((m->flags & (PG_BUSY|PG_UNMANAGED)) || m->busy ||
/*
* occassionally leave the page alone
*/
- crit_enter();
lwkt_gettoken(&vm_token);
if ((dnw & 0x01F0) == 0 ||
m->queue == PQ_INACTIVE ||
if (m->act_count >= ACT_INIT)
--m->act_count;
lwkt_reltoken(&vm_token);
- crit_exit();
return;
}
}
_vm_page_deactivate(m, head);
lwkt_reltoken(&vm_token);
- crit_exit();
}
/*
KKASSERT(allocflags &
(VM_ALLOC_NORMAL|VM_ALLOC_INTERRUPT|VM_ALLOC_SYSTEM));
- crit_enter();
lwkt_gettoken(&vm_token);
retrylookup:
if ((m = vm_page_lookup(object, pindex)) != NULL) {
}
done:
lwkt_reltoken(&vm_token);
- crit_exit();
return(m);
}