svn commit: r337262 - in stable/11/sys: amd64/amd64 i386/i386 kern vm

Mark Johnston markj at FreeBSD.org
Fri Aug 3 15:42:41 UTC 2018


Author: markj
Date: Fri Aug  3 15:42:39 2018
New Revision: 337262
URL: https://svnweb.freebsd.org/changeset/base/337262

Log:
  MFC r336505, r336764
  Have preload_delete_name() free pages backing preloaded data.

Modified:
  stable/11/sys/amd64/amd64/machdep.c
  stable/11/sys/amd64/amd64/pmap.c
  stable/11/sys/i386/i386/machdep.c
  stable/11/sys/i386/i386/pmap.c
  stable/11/sys/kern/subr_module.c
  stable/11/sys/vm/vm_extern.h
  stable/11/sys/vm/vm_kern.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/amd64/amd64/machdep.c
==============================================================================
--- stable/11/sys/amd64/amd64/machdep.c	Fri Aug  3 15:35:29 2018	(r337261)
+++ stable/11/sys/amd64/amd64/machdep.c	Fri Aug  3 15:42:39 2018	(r337262)
@@ -100,6 +100,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_object.h>
 #include <vm/vm_pager.h>
 #include <vm/vm_param.h>
+#include <vm/vm_phys.h>
 
 #ifdef DDB
 #ifndef KDB
@@ -1229,6 +1230,12 @@ getmemsize(caddr_t kmdp, u_int64_t first)
 	pt_entry_t *pte;
 	quad_t dcons_addr, dcons_size;
 	int page_counter;
+
+	/*
+	 * Tell the physical memory allocator about pages used to store
+	 * the kernel and preloaded data.  See kmem_bootstrap_free().
+	 */
+	vm_phys_add_seg((vm_paddr_t)kernphys, trunc_page(first));
 
 	bzero(physmap, sizeof(physmap));
 	physmap_idx = 0;

Modified: stable/11/sys/amd64/amd64/pmap.c
==============================================================================
--- stable/11/sys/amd64/amd64/pmap.c	Fri Aug  3 15:35:29 2018	(r337261)
+++ stable/11/sys/amd64/amd64/pmap.c	Fri Aug  3 15:42:39 2018	(r337262)
@@ -373,6 +373,8 @@ static u_int64_t	DMPDphys;	/* phys addr of direct mapp
 static u_int64_t	DMPDPphys;	/* phys addr of direct mapped level 3 */
 static int		ndmpdpphys;	/* number of DMPDPphys pages */
 
+static vm_paddr_t	KERNend;	/* phys addr of end of bootstrap data */
+
 /*
  * pmap_mapdev support pre initialization (i.e. console)
  */
@@ -938,8 +940,9 @@ create_pagetables(vm_paddr_t *firstaddr)
 	/* Map from zero to end of allocations under 2M pages */
 	/* This replaces some of the KPTphys entries above */
 	for (i = 0; (i << PDRSHIFT) < *firstaddr; i++)
+		/* Preset PG_M and PG_A because demotion expects it. */
 		pd_p[i] = (i << PDRSHIFT) | X86_PG_RW | X86_PG_V | PG_PS |
-		    pg_g;
+		    X86_PG_M | X86_PG_A | pg_g;
 
 	/*
 	 * Because we map the physical blocks in 2M pages, adjust firstaddr
@@ -1015,6 +1018,8 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
 	pt_entry_t *pte;
 	int i;
 
+	KERNend = *firstaddr;
+
 	if (!pti)
 		pg_g = X86_PG_G;
 
@@ -1247,6 +1252,7 @@ pmap_init(void)
 	 * Initialize the vm page array entries for the kernel pmap's
 	 * page table pages.
 	 */ 
+	PMAP_LOCK(kernel_pmap);
 	for (i = 0; i < nkpt; i++) {
 		mpte = PHYS_TO_VM_PAGE(KPTphys + (i << PAGE_SHIFT));
 		KASSERT(mpte >= vm_page_array &&
@@ -1255,7 +1261,11 @@ pmap_init(void)
 		mpte->pindex = pmap_pde_pindex(KERNBASE) + i;
 		mpte->phys_addr = KPTphys + (i << PAGE_SHIFT);
 		mpte->wire_count = 1;
+		if (i << PDRSHIFT < KERNend &&
+		    pmap_insert_pt_page(kernel_pmap, mpte))
+			panic("pmap_init: pmap_insert_pt_page failed");
 	}
+	PMAP_UNLOCK(kernel_pmap);
 	atomic_add_int(&vm_cnt.v_wire_count, nkpt);
 
 	/*

Modified: stable/11/sys/i386/i386/machdep.c
==============================================================================
--- stable/11/sys/i386/i386/machdep.c	Fri Aug  3 15:35:29 2018	(r337261)
+++ stable/11/sys/i386/i386/machdep.c	Fri Aug  3 15:42:39 2018	(r337262)
@@ -99,6 +99,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_object.h>
 #include <vm/vm_pager.h>
 #include <vm/vm_param.h>
+#include <vm/vm_phys.h>
 
 #ifdef DDB
 #ifndef KDB
@@ -2074,6 +2075,12 @@ getmemsize(int first)
 	bzero(&vmf, sizeof(vmf));
 	bzero(physmap, sizeof(physmap));
 	basemem = 0;
+
+	/*
+	 * Tell the physical memory allocator about pages used to store
+	 * the kernel and preloaded data.  See kmem_bootstrap_free().
+	 */
+	vm_phys_add_seg((vm_paddr_t)KERNLOAD, trunc_page(first));
 
 	/*
 	 * Check if the loader supplied an SMAP memory map.  If so,

Modified: stable/11/sys/i386/i386/pmap.c
==============================================================================
--- stable/11/sys/i386/i386/pmap.c	Fri Aug  3 15:35:29 2018	(r337261)
+++ stable/11/sys/i386/i386/pmap.c	Fri Aug  3 15:42:39 2018	(r337262)
@@ -787,6 +787,7 @@ pmap_init(void)
 	 * Initialize the vm page array entries for the kernel pmap's
 	 * page table pages.
 	 */ 
+	PMAP_LOCK(kernel_pmap);
 	for (i = 0; i < NKPT; i++) {
 		mpte = PHYS_TO_VM_PAGE(KPTphys + (i << PAGE_SHIFT));
 		KASSERT(mpte >= vm_page_array &&
@@ -794,7 +795,14 @@ pmap_init(void)
 		    ("pmap_init: page table page is out of range"));
 		mpte->pindex = i + KPTDI;
 		mpte->phys_addr = KPTphys + (i << PAGE_SHIFT);
+		mpte->wire_count = 1;
+		if (pseflag != 0 &&
+		    KERNBASE <= i << PDRSHIFT && i << PDRSHIFT < KERNend &&
+		    pmap_insert_pt_page(kernel_pmap, mpte))
+			panic("pmap_init: pmap_insert_pt_page failed");
 	}
+	PMAP_UNLOCK(kernel_pmap);
+	vm_wire_add(NKPT);
 
 	/*
 	 * Initialize the address space (zone) for the pv entries.  Set a

Modified: stable/11/sys/kern/subr_module.c
==============================================================================
--- stable/11/sys/kern/subr_module.c	Fri Aug  3 15:35:29 2018	(r337261)
+++ stable/11/sys/kern/subr_module.c	Fri Aug  3 15:42:39 2018	(r337262)
@@ -31,6 +31,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/linker.h>
 
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+
 /*
  * Preloaded module support
  */
@@ -202,29 +205,42 @@ preload_search_info(caddr_t mod, int inf)
 void
 preload_delete_name(const char *name)
 {
-    caddr_t	curp;
-    uint32_t	*hdr;
+    caddr_t	addr, curp;
+    uint32_t	*hdr, sz;
     int		next;
     int		clearing;
+
+    addr = 0;
+    sz = 0;
     
     if (preload_metadata != NULL) {
-	
+
 	clearing = 0;
 	curp = preload_metadata;
 	for (;;) {
 	    hdr = (uint32_t *)curp;
-	    if (hdr[0] == 0 && hdr[1] == 0)
-		break;
+	    if (hdr[0] == MODINFO_NAME || (hdr[0] == 0 && hdr[1] == 0)) {
+		/* Free memory used to store the file. */
+		if (addr != 0 && sz != 0)
+		    kmem_bootstrap_free((vm_offset_t)addr, sz);
+		addr = 0;
+		sz = 0;
 
-	    /* Search for a MODINFO_NAME field */
-	    if (hdr[0] == MODINFO_NAME) {
+		if (hdr[0] == 0)
+		    break;
 		if (!strcmp(name, curp + sizeof(uint32_t) * 2))
 		    clearing = 1;	/* got it, start clearing */
-		else if (clearing)
+		else if (clearing) {
 		    clearing = 0;	/* at next one now.. better stop */
+		}
 	    }
-	    if (clearing)
+	    if (clearing) {
+		if (hdr[0] == MODINFO_ADDR)
+		    addr = *(caddr_t *)(curp + sizeof(uint32_t) * 2);
+		else if (hdr[0] == MODINFO_SIZE)
+		    sz = *(uint32_t *)(curp + sizeof(uint32_t) * 2);
 		hdr[0] = MODINFO_EMPTY;
+	    }
 
 	    /* skip to next field */
 	    next = sizeof(uint32_t) * 2 + hdr[1];

Modified: stable/11/sys/vm/vm_extern.h
==============================================================================
--- stable/11/sys/vm/vm_extern.h	Fri Aug  3 15:35:29 2018	(r337261)
+++ stable/11/sys/vm/vm_extern.h	Fri Aug  3 15:42:39 2018	(r337262)
@@ -65,6 +65,7 @@ int kmem_back(vm_object_t, vm_offset_t, vm_size_t, int
 void kmem_unback(vm_object_t, vm_offset_t, vm_size_t);
 
 /* Bootstrapping. */
+void kmem_bootstrap_free(vm_offset_t, vm_size_t);
 vm_map_t kmem_suballoc(vm_map_t, vm_offset_t *, vm_offset_t *, vm_size_t,
     boolean_t);
 void kmem_init(vm_offset_t, vm_offset_t);

Modified: stable/11/sys/vm/vm_kern.c
==============================================================================
--- stable/11/sys/vm/vm_kern.c	Fri Aug  3 15:35:29 2018	(r337261)
+++ stable/11/sys/vm/vm_kern.c	Fri Aug  3 15:42:39 2018	(r337262)
@@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_object.h>
 #include <vm/vm_page.h>
 #include <vm/vm_pageout.h>
+#include <vm/vm_phys.h>
 #include <vm/vm_radix.h>
 #include <vm/vm_extern.h>
 #include <vm/uma.h>
@@ -535,6 +536,37 @@ kmem_init(vm_offset_t start, vm_offset_t end)
 	    start, VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT);
 	/* ... and ending with the completion of the above `insert' */
 	vm_map_unlock(m);
+}
+
+/*
+ *	kmem_bootstrap_free:
+ *
+ *	Free pages backing preloaded data (e.g., kernel modules) to the
+ *	system.  Currently only supported on platforms that create a
+ *	vm_phys segment for preloaded data.
+ */
+void
+kmem_bootstrap_free(vm_offset_t start, vm_size_t size)
+{
+#if defined(__i386__) || defined(__amd64__)
+	vm_offset_t end, va;
+	vm_paddr_t pa;
+	vm_page_t m;
+
+	end = trunc_page(start + size);
+	start = round_page(start);
+
+	for (va = start; va < end; va += PAGE_SIZE) {
+		pa = pmap_kextract(va);
+		m = PHYS_TO_VM_PAGE(pa);
+
+		mtx_lock(&vm_page_queue_free_mtx);
+		vm_phys_free_pages(m, 0);
+		mtx_unlock(&vm_page_queue_free_mtx);
+	}
+	pmap_remove(kernel_pmap, start, end);
+	(void)vmem_add(kernel_arena, start, end - start, M_WAITOK);
+#endif
 }
 
 #ifdef DIAGNOSTIC


More information about the svn-src-stable-11 mailing list