From owner-svn-src-all@freebsd.org Thu Jul 19 20:00:30 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0B1E51047D0D; Thu, 19 Jul 2018 20:00:30 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id B56377791B; Thu, 19 Jul 2018 20:00:29 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 919E12DCFD; Thu, 19 Jul 2018 20:00:29 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w6JK0TpL029150; Thu, 19 Jul 2018 20:00:29 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w6JK0SBI029146; Thu, 19 Jul 2018 20:00:28 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201807192000.w6JK0SBI029146@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Thu, 19 Jul 2018 20:00:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r336505 - in head/sys: amd64/amd64 i386/i386 kern vm X-SVN-Group: head X-SVN-Commit-Author: markj X-SVN-Commit-Paths: in head/sys: amd64/amd64 i386/i386 kern vm X-SVN-Commit-Revision: 336505 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Jul 2018 20:00:30 -0000 Author: markj Date: Thu Jul 19 20:00:28 2018 New Revision: 336505 URL: https://svnweb.freebsd.org/changeset/base/336505 Log: Have preload_delete_name() free pages backing preloaded data. On i386 and amd64, add a vm_phys segment for physical memory used to store the kernel binary and other preloaded data. This makes it possible to free such memory back to the system once it is no longer needed, e.g., when a preloaded kernel module is unloaded. Previously, it would have remained unused. Reviewed by: kib, royger MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D16330 Modified: head/sys/amd64/amd64/machdep.c head/sys/i386/i386/machdep.c head/sys/kern/subr_module.c head/sys/vm/vm_extern.h head/sys/vm/vm_kern.c Modified: head/sys/amd64/amd64/machdep.c ============================================================================== --- head/sys/amd64/amd64/machdep.c Thu Jul 19 19:50:42 2018 (r336504) +++ head/sys/amd64/amd64/machdep.c Thu Jul 19 20:00:28 2018 (r336505) @@ -101,6 +101,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #ifdef DDB #ifndef KDB @@ -1226,6 +1227,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: head/sys/i386/i386/machdep.c ============================================================================== --- head/sys/i386/i386/machdep.c Thu Jul 19 19:50:42 2018 (r336504) +++ head/sys/i386/i386/machdep.c Thu Jul 19 20:00:28 2018 (r336505) @@ -101,6 +101,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #ifdef DDB #ifndef KDB @@ -1832,6 +1833,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: head/sys/kern/subr_module.c ============================================================================== --- head/sys/kern/subr_module.c Thu Jul 19 19:50:42 2018 (r336504) +++ head/sys/kern/subr_module.c Thu Jul 19 20:00:28 2018 (r336505) @@ -33,6 +33,9 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include + /* * Preloaded module support */ @@ -204,29 +207,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: head/sys/vm/vm_extern.h ============================================================================== --- head/sys/vm/vm_extern.h Thu Jul 19 19:50:42 2018 (r336504) +++ head/sys/vm/vm_extern.h Thu Jul 19 20:00:28 2018 (r336505) @@ -75,6 +75,7 @@ int kmem_back_domain(int, vm_object_t, vm_offset_t, vm 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: head/sys/vm/vm_kern.c ============================================================================== --- head/sys/vm/vm_kern.c Thu Jul 19 19:50:42 2018 (r336504) +++ head/sys/vm/vm_kern.c Thu Jul 19 20:00:28 2018 (r336505) @@ -688,6 +688,38 @@ kmem_init(vm_offset_t start, vm_offset_t end) 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__) + struct vm_domain *vmd; + vm_offset_t end; + vm_paddr_t pa; + vm_page_t m; + + end = trunc_page(start + size); + start = round_page(start); + + (void)vm_map_remove(kernel_map, start, end); + for (; start < end; start += PAGE_SIZE) { + pa = pmap_kextract(start); + m = PHYS_TO_VM_PAGE(pa); + + vmd = vm_pagequeue_domain(m); + vm_domain_free_lock(vmd); + vm_phys_free_pages(m, 0); + vm_domain_free_unlock(vmd); + } +#endif +} + #ifdef DIAGNOSTIC /* * Allow userspace to directly trigger the VM drain routine for testing