PERFORCE change 94196 for review

Peter Wemm peter at FreeBSD.org
Tue Mar 28 19:51:56 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=94196

Change 94196 by peter at peter_daintree on 2006/03/28 19:18:56

	Oops. If we skipped a pv entry due to a wired page, we can't free
	the chunk.  Let the final vm_map based rundown clean it up.

Affected files ...

.. //depot/projects/hammer/sys/amd64/amd64/pmap.c#146 edit

Differences ...

==== //depot/projects/hammer/sys/amd64/amd64/pmap.c#146 (text+ko) ====

@@ -2700,6 +2700,7 @@
 	int field, idx;
 	int64_t bit;
 	uint64_t inuse;
+	int allfree;
 
 	if (pmap != vmspace_pmap(curthread->td_proc->p_vmspace)) {
 		printf("warning: pmap_remove_pages called with non-current pmap\n");
@@ -2713,6 +2714,7 @@
 		 * after all because we still have to work around the
 		 * skipping of a PG_W page.  oops.
 		 */
+		allfree = 1;
 		for (field = 0; field < _NPCM; field++) {
 			inuse = (~(pc->pc_map[field])) & pc_freemask[field];
 			while (inuse != 0) {
@@ -2734,8 +2736,10 @@
 /*
  * We cannot remove wired pages from a process' mapping at this time
  */
-				if (tpte & PG_W)
+				if (tpte & PG_W) {
+					allfree = 0;
 					continue;
+				}
 
 				m = PHYS_TO_VM_PAGE(tpte & PG_FRAME);
 				KASSERT(m->phys_addr == (tpte & PG_FRAME),
@@ -2770,14 +2774,16 @@
 				    *vtopde(pv->pv_va));
 			}
 		}
-		pv_entry_spare -= _NPCPV;
-		pc_chunk_count--;
-		pc_chunk_frees++;
-		TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
-		m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pc));
-		vm_page_lock_queues();
-		vm_page_free(m);
-		vm_page_unlock_queues();
+		if (allfree) {
+			pv_entry_spare -= _NPCPV;
+			pc_chunk_count--;
+			pc_chunk_frees++;
+			TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
+			m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pc));
+			vm_page_lock_queues();
+			vm_page_free(m);
+			vm_page_unlock_queues();
+		}
 	}
 	pmap_invalidate_all(pmap);
 	PMAP_UNLOCK(pmap);


More information about the p4-projects mailing list