From owner-svn-src-all@freebsd.org Thu Dec 3 05:39:27 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id C638347ADD7; Thu, 3 Dec 2020 05:39:27 +0000 (UTC) (envelope-from gonzo@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Cml5W5JTRz4p7V; Thu, 3 Dec 2020 05:39:27 +0000 (UTC) (envelope-from gonzo@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 A8FAB140D8; Thu, 3 Dec 2020 05:39:27 +0000 (UTC) (envelope-from gonzo@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0B35dRWN081695; Thu, 3 Dec 2020 05:39:27 GMT (envelope-from gonzo@FreeBSD.org) Received: (from gonzo@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0B35dRsY081694; Thu, 3 Dec 2020 05:39:27 GMT (envelope-from gonzo@FreeBSD.org) Message-Id: <202012030539.0B35dRsY081694@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: gonzo set sender to gonzo@FreeBSD.org using -f From: Oleksandr Tymoshenko Date: Thu, 3 Dec 2020 05:39:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r368293 - head/sys/kern X-SVN-Group: head X-SVN-Commit-Author: gonzo X-SVN-Commit-Paths: head/sys/kern X-SVN-Commit-Revision: 368293 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.34 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, 03 Dec 2020 05:39:27 -0000 Author: gonzo Date: Thu Dec 3 05:39:27 2020 New Revision: 368293 URL: https://svnweb.freebsd.org/changeset/base/368293 Log: Add support for hw.physmem tunable for ARM/ARM64/RISC-V platforms hw.physmem tunable allows to limit number of physical memory available to the system. It's handled in machdep files for x86 and PowerPC. This patch adds required logic to the consolidated physmem management interface that is used by ARM, ARM64, and RISC-V. Submitted by: Klara, Inc. Reviewed by: mhorne Sponsored by: Ampere Computing Differential Revision: https://reviews.freebsd.org/D27152 Modified: head/sys/kern/subr_physmem.c Modified: head/sys/kern/subr_physmem.c ============================================================================== --- head/sys/kern/subr_physmem.c Thu Dec 3 02:22:05 2020 (r368292) +++ head/sys/kern/subr_physmem.c Thu Dec 3 05:39:27 2020 (r368293) @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -141,6 +142,10 @@ physmem_print_tables(void) /* * Walk the list of hardware regions, processing it against the list of * exclusions that contain the given exflags, and generating an "avail list". + * + * If maxphyssz is not zero it sets upper limit, in bytes, for the total + * "avail list" size. Walk stops once the limit is reached and the last region + * is cut short if necessary. * * Updates the value at *pavail with the sum of all pages in all hw regions. * @@ -148,15 +153,17 @@ physmem_print_tables(void) */ static size_t regions_to_avail(vm_paddr_t *avail, uint32_t exflags, size_t maxavail, - long *pavail, long *prealmem) + uint64_t maxphyssz, long *pavail, long *prealmem) { size_t acnt, exi, hwi; uint64_t end, start, xend, xstart; long availmem, totalmem; const struct region *exp, *hwp; + uint64_t availsz; totalmem = 0; availmem = 0; + availsz = 0; acnt = 0; for (hwi = 0, hwp = hwregions; hwi < hwcnt; ++hwi, ++hwp) { start = hwp->addr; @@ -202,6 +209,13 @@ regions_to_avail(vm_paddr_t *avail, uint32_t exflags, * could affect the remainder of this hw region. */ if ((xstart > start) && (xend < end)) { + + if ((maxphyssz != 0) && + (availsz + xstart - start > maxphyssz)) { + xstart = maxphyssz + start - availsz; + } + if (xstart <= start) + continue; if (acnt > 0 && avail[acnt - 1] == (vm_paddr_t)start) { avail[acnt - 1] = (vm_paddr_t)xstart; @@ -209,6 +223,7 @@ regions_to_avail(vm_paddr_t *avail, uint32_t exflags, avail[acnt++] = (vm_paddr_t)start; avail[acnt++] = (vm_paddr_t)xstart; } + availsz += (xstart - start); availmem += atop((vm_offset_t)(xstart - start)); start = xend; continue; @@ -228,12 +243,20 @@ regions_to_avail(vm_paddr_t *avail, uint32_t exflags, * available entry for it. */ if (end > start) { + if ((maxphyssz != 0) && + (availsz + end - start > maxphyssz)) { + end = maxphyssz + start - availsz; + } + if (end <= start) + break; + if (acnt > 0 && avail[acnt - 1] == (vm_paddr_t)start) { avail[acnt - 1] = (vm_paddr_t)end; } else { avail[acnt++] = (vm_paddr_t)start; avail[acnt++] = (vm_paddr_t)end; } + availsz += end - start; availmem += atop((vm_offset_t)(end - start)); } if (acnt >= maxavail) @@ -362,7 +385,7 @@ size_t physmem_avail(vm_paddr_t *avail, size_t maxavail) { - return (regions_to_avail(avail, EXFLAG_NOALLOC, maxavail, NULL, NULL)); + return (regions_to_avail(avail, EXFLAG_NOALLOC, maxavail, 0, NULL, NULL)); } /* @@ -378,11 +401,15 @@ void physmem_init_kernel_globals(void) { size_t nextidx; + u_long hwphyssz; - regions_to_avail(dump_avail, EXFLAG_NODUMP, PHYS_AVAIL_ENTRIES, NULL, - NULL); + hwphyssz = 0; + TUNABLE_ULONG_FETCH("hw.physmem", &hwphyssz); + + regions_to_avail(dump_avail, EXFLAG_NODUMP, PHYS_AVAIL_ENTRIES, + hwphyssz, NULL, NULL); nextidx = regions_to_avail(phys_avail, EXFLAG_NOALLOC, - PHYS_AVAIL_ENTRIES, &physmem, &realmem); + PHYS_AVAIL_ENTRIES, hwphyssz, &physmem, &realmem); if (nextidx == 0) panic("No memory entries in phys_avail"); Maxmem = atop(phys_avail[nextidx - 1]);