Include the psind in data returned by mincore(2).

Currently we use a single bit to indicate whether the virtual page is
part of a superpage.  To support a forthcoming implementation of
non-transparent 1GB superpages, it is useful to provide more detailed
information about large page sizes.

The change converts MINCORE_SUPER into a mask for MINCORE_PSIND(psind)
values, indicating a mapping of size psind, where psind is an index into
the pagesizes array returned by getpagesizes(3), which in turn comes
from the hw.pagesizes sysctl.  MINCORE_PSIND(1) is equal to the old
value of MINCORE_SUPER.

For now, two bits are used to record the page size, permitting values
of MAXPAGESIZES up to 4.

Reviewed by:	alc, kib
Sponsored by:	Juniper Networks, Inc.
Sponsored by:	Klara, Inc.
Differential Revision:	https://reviews.freebsd.org/D26238
This commit is contained in:
Mark Johnston 2020-09-02 18:16:43 +00:00
parent 2825bf5b2a
commit 847ab36bf2
9 changed files with 35 additions and 10 deletions

View File

@ -28,7 +28,7 @@
.\" @(#)mincore.2 8.1 (Berkeley) 6/9/93
.\" $FreeBSD$
.\"
.Dd January 7, 2019
.Dd August 23, 2020
.Dt MINCORE 2
.Os
.Sh NAME
@ -73,9 +73,19 @@ Page has been modified by us.
Page has been referenced.
.It Dv MINCORE_MODIFIED_OTHER
Page has been modified.
.It Dv MINCORE_SUPER
.It Dv MINCORE_PSIND(i)
Page is part of a large
.Pq Dq super
page with size given by index
.Dv i
in the array returned by
.Xr getpagesizes 3 .
.It Dv MINCORE_SUPER
A mask of the valid
.Dv MINCORE_PSIND()
values.
If any bits in this mask are set, the page is part of a large
.Pq Dq super
page.
.El
.Pp
@ -98,6 +108,17 @@ and
statuses.
Otherwise, if the sysctl value is zero, all resident pages backing the
specified address range are examined, regardless of the mapping state.
.Sh IMPLEMENTATION NOTES
Prior to the introduction of
.Dv MINCORE_PSIND()
in
.Fx 13.0 ,
.Dv MINCORE_SUPER
consisted of a single bit equal to
.Dv MINCORE_PSIND(1) .
In particular, applications compiled using the old value of
.Dv MINCORE_SUPER
will not identify large pages with size index 2 as being large pages.
.Sh RETURN VALUES
.Rv -std mincore
.Sh ERRORS
@ -122,7 +143,8 @@ argument points to an illegal address.
.Xr mprotect 2 ,
.Xr msync 2 ,
.Xr munmap 2 ,
.Xr getpagesize 3
.Xr getpagesize 3 ,
.Xr getpagesizes 3
.Sh HISTORY
The
.Fn mincore

View File

@ -9149,7 +9149,7 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *pap)
/* Compute the physical address of the 4KB page. */
pa = ((*pdep & PG_PS_FRAME) | (addr & PDRMASK)) &
PG_FRAME;
val = MINCORE_SUPER;
val = MINCORE_PSIND(1);
} else {
pte = *pmap_pde_to_pte(pdep, addr);
pa = pte & PG_FRAME;

View File

@ -6235,7 +6235,7 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *pap)
if (pte1_is_section(pte1)) {
pa = trunc_page(pte1_pa(pte1) | (addr & PTE1_OFFSET));
managed = pte1_is_managed(pte1);
val = MINCORE_SUPER | MINCORE_INCORE;
val = MINCORE_PSIND(1) | MINCORE_INCORE;
if (pte1_is_dirty(pte1))
val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER;
if (pte1 & PTE1_A)

View File

@ -5956,7 +5956,7 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *pap)
managed = (tpte & ATTR_SW_MANAGED) != 0;
val = MINCORE_INCORE;
if (lvl != 3)
val |= MINCORE_SUPER;
val |= MINCORE_PSIND(3 - lvl);
if ((managed && pmap_pte_dirty(pmap, tpte)) || (!managed &&
(tpte & ATTR_S1_AP_RW_BIT) == ATTR_S1_AP(ATTR_S1_AP_RW)))
val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER;

View File

@ -5755,7 +5755,7 @@ __CONCAT(PMTYPE, mincore)(pmap_t pmap, vm_offset_t addr, vm_paddr_t *pap)
/* Compute the physical address of the 4KB page. */
pa = ((pde & PG_PS_FRAME) | (addr & PDRMASK)) &
PG_FRAME;
val = MINCORE_SUPER;
val = MINCORE_PSIND(1);
} else {
pte = pmap_pte_ufast(pmap, addr, pde);
pa = pte & PG_FRAME;

View File

@ -5689,7 +5689,7 @@ mmu_radix_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *locked_pa)
/* Compute the physical address of the 4KB page. */
pa = ((*l3ep & PG_PS_FRAME) | (addr & L3_PAGE_MASK)) &
PG_FRAME;
val = MINCORE_SUPER;
val = MINCORE_PSIND(1);
} else {
pte = *pmap_l3e_to_pte(l3ep, addr);
pa = pte & PG_FRAME;

View File

@ -4217,7 +4217,7 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *pap)
if (l2 != NULL && ((tpte = pmap_load(l2)) & PTE_V) != 0) {
if ((tpte & PTE_RWX) != 0) {
pa = PTE_TO_PHYS(tpte) | (addr & L2_OFFSET);
val = MINCORE_INCORE | MINCORE_SUPER;
val = MINCORE_INCORE | MINCORE_PSIND(1);
} else {
l3 = pmap_l2_to_l3(l2, addr);
tpte = pmap_load(l3);

View File

@ -179,7 +179,8 @@
#define MINCORE_MODIFIED 0x4 /* Page has been modified by us */
#define MINCORE_REFERENCED_OTHER 0x8 /* Page has been referenced */
#define MINCORE_MODIFIED_OTHER 0x10 /* Page has been modified */
#define MINCORE_SUPER 0x20 /* Page is a "super" page */
#define MINCORE_SUPER 0x60 /* Page is a "super" page */
#define MINCORE_PSIND(i) (((i) << 5) & MINCORE_SUPER) /* Page size */
/*
* Anonymous object constant for shm_open().

View File

@ -112,6 +112,8 @@ SYSCTL_INT(_vm, OID_AUTO, imply_prot_max, CTLFLAG_RWTUN, &imply_prot_max, 0,
#define MAP_32BIT_MAX_ADDR ((vm_offset_t)1 << 31)
#endif
_Static_assert(MAXPAGESIZES <= 4, "MINCORE_SUPER too narrow");
#ifndef _SYS_SYSPROTO_H_
struct sbrk_args {
int incr;