svn commit: r195416 - head/sys/amd64/amd64

Alan Cox alc at FreeBSD.org
Mon Jul 6 18:43:43 UTC 2009


Author: alc
Date: Mon Jul  6 18:43:42 2009
New Revision: 195416
URL: http://svn.freebsd.org/changeset/base/195416

Log:
  When pmap_change_attr() changes the PAT setting on a kernel mapping, it has
  to simultaneously change the PAT setting for the same pages within the
  direct map region.  This may require the demotion of a 2MB page mapping and
  the allocation of a page table page.  This revision gives the highest
  possible priority (VM_ALLOC_INTERRUPT) to this page allocation, so that
  pmap_change_attr() is less likely to fail.  (In general, kernel page table
  page allocations have the highest priority, so this is not creating a new
  precedent.)
  
  (Demotion of 1GB page mappings within the direct map already specifies
  VM_ALLOC_INTERRUPT to vm_page_alloc(), so only pmap_demote_pde() must be
  changed.)
  
  Approved by:	re (kib)

Modified:
  head/sys/amd64/amd64/pmap.c

Modified: head/sys/amd64/amd64/pmap.c
==============================================================================
--- head/sys/amd64/amd64/pmap.c	Mon Jul  6 18:23:00 2009	(r195415)
+++ head/sys/amd64/amd64/pmap.c	Mon Jul  6 18:43:42 2009	(r195416)
@@ -2218,11 +2218,19 @@ pmap_demote_pde(pmap_t pmap, pd_entry_t 
 		/*
 		 * Invalidate the 2MB page mapping and return "failure" if the
 		 * mapping was never accessed or the allocation of the new
-		 * page table page fails.
+		 * page table page fails.  If the 2MB page mapping belongs to
+		 * the direct map region of the kernel's address space, then
+		 * the page allocation request specifies the highest possible
+		 * priority (VM_ALLOC_INTERRUPT).  Otherwise, the priority is
+		 * normal.  Page table pages are preallocated for every other
+		 * part of the kernel address space, so the direct map region
+		 * is the only part of the kernel address space that must be
+		 * handled here.
 		 */
 		if ((oldpde & PG_A) == 0 || (mpte = vm_page_alloc(NULL,
-		    pmap_pde_pindex(va), VM_ALLOC_NOOBJ | VM_ALLOC_NORMAL |
-		    VM_ALLOC_WIRED)) == NULL) {
+		    pmap_pde_pindex(va), (va >= DMAP_MIN_ADDRESS && va <
+		    DMAP_MAX_ADDRESS ? VM_ALLOC_INTERRUPT : VM_ALLOC_NORMAL) |
+		    VM_ALLOC_NOOBJ | VM_ALLOC_WIRED)) == NULL) {
 			free = NULL;
 			pmap_remove_pde(pmap, pde, trunc_2mpage(va), &free);
 			pmap_invalidate_page(pmap, trunc_2mpage(va));


More information about the svn-src-head mailing list