git: 5567d6b4419b - main - arm64 pmap: Simplify logic around pv_chunk sizes.

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Wed, 17 Aug 2022 19:11:07 UTC
The branch main has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=5567d6b4419b02a2099527228b1a51cc55a5b47d

commit 5567d6b4419b02a2099527228b1a51cc55a5b47d
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2022-08-17 19:10:12 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2022-08-17 19:10:12 +0000

    arm64 pmap: Simplify logic around pv_chunk sizes.
    
    - Define PC_FREEL and _NPCM in terms of _NPCPV rather than via magic
      numbers.
    
    - Remove assertions about _NPC* values from pmap.c.  This is less
      relevant now that PC_FREEL and _NPCM are derived from _NPCPV.
    
    - Add a helper inline function pc_is_full() which uses a loop to check
      if pc_map is all zeroes.  Use this to replace three places that
      check for a full mask assuming there are only 3 entries in pc_map.
    
    Reviewed by:    markj
    Sponsored by:   DARPA
    Differential Revision:  https://reviews.freebsd.org/D36217
---
 sys/arm64/arm64/pmap.c   | 30 +++++++++++++-----------------
 sys/arm64/include/pmap.h |  3 +--
 2 files changed, 14 insertions(+), 19 deletions(-)

diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index 62276c024212..9c47c043d251 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -2449,13 +2449,6 @@ pmap_growkernel(vm_offset_t addr)
  ***************************************************/
 
 CTASSERT(sizeof(struct pv_chunk) == PAGE_SIZE);
-#if PAGE_SIZE == PAGE_SIZE_4K
-CTASSERT(_NPCM == 3);
-CTASSERT(_NPCPV == 168);
-#else
-CTASSERT(_NPCM == 11);
-CTASSERT(_NPCPV == 677);
-#endif
 
 static __inline struct pv_chunk *
 pv_to_chunk(pv_entry_t pv)
@@ -2467,11 +2460,7 @@ pv_to_chunk(pv_entry_t pv)
 #define PV_PMAP(pv) (pv_to_chunk(pv)->pc_pmap)
 
 #define	PC_FREEN	0xfffffffffffffffful
-#if _NPCM == 3
-#define	PC_FREEL	0x000000fffffffffful
-#elif _NPCM == 11
-#define	PC_FREEL	0x0000001ffffffffful
-#endif
+#define	PC_FREEL	((1ul << (_NPCPV % 64)) - 1)
 
 #if _NPCM == 3
 #define	PC_IS_FREE(pc)	((pc)->pc_map[0] == PC_FREEN &&			\
@@ -2491,6 +2480,15 @@ static const uint64_t pc_freemask[] = { PC_FREEN, PC_FREEN,
 
 CTASSERT(nitems(pc_freemask) == _NPCM);
 
+static __inline bool
+pc_is_full(struct pv_chunk *pc)
+{
+	for (u_int i = 0; i < _NPCM; i++)
+		if (pc->pc_map[i] != 0)
+			return (false);
+	return (true);
+}
+
 #ifdef PV_STATS
 static int pc_chunk_count, pc_chunk_allocs, pc_chunk_frees, pc_chunk_tryfail;
 
@@ -2785,8 +2783,7 @@ retry:
 			pv = &pc->pc_pventry[field * 64 + bit];
 			pc->pc_map[field] &= ~(1ul << bit);
 			/* If this was the last item, move it to tail */
-			if (pc->pc_map[0] == 0 && pc->pc_map[1] == 0 &&
-			    pc->pc_map[2] == 0) {
+			if (pc_is_full(pc)) {
 				TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
 				TAILQ_INSERT_TAIL(&pmap->pm_pvchunk, pc,
 				    pc_list);
@@ -2953,8 +2950,7 @@ pmap_pv_demote_l2(pmap_t pmap, vm_offset_t va, vm_paddr_t pa,
 	va_last = va + L2_SIZE - PAGE_SIZE;
 	for (;;) {
 		pc = TAILQ_FIRST(&pmap->pm_pvchunk);
-		KASSERT(pc->pc_map[0] != 0 || pc->pc_map[1] != 0 ||
-		    pc->pc_map[2] != 0, ("pmap_pv_demote_l2: missing spare"));
+		KASSERT(!pc_is_full(pc), ("pmap_pv_demote_l2: missing spare"));
 		for (field = 0; field < _NPCM; field++) {
 			while (pc->pc_map[field]) {
 				bit = ffsl(pc->pc_map[field]) - 1;
@@ -2975,7 +2971,7 @@ pmap_pv_demote_l2(pmap_t pmap, vm_offset_t va, vm_paddr_t pa,
 		TAILQ_INSERT_TAIL(&pmap->pm_pvchunk, pc, pc_list);
 	}
 out:
-	if (pc->pc_map[0] == 0 && pc->pc_map[1] == 0 && pc->pc_map[2] == 0) {
+	if (pc_is_full(pc)) {
 		TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
 		TAILQ_INSERT_TAIL(&pmap->pm_pvchunk, pc, pc_list);
 	}
diff --git a/sys/arm64/include/pmap.h b/sys/arm64/include/pmap.h
index f36b081ea869..9605c813285b 100644
--- a/sys/arm64/include/pmap.h
+++ b/sys/arm64/include/pmap.h
@@ -107,16 +107,15 @@ typedef struct pv_entry {
  * need to track per-pmap assignments.
  */
 #if PAGE_SIZE == PAGE_SIZE_4K
-#define	_NPCM	3
 #define	_NPCPV	168
 #define	_NPAD	0
 #elif PAGE_SIZE == PAGE_SIZE_16K
-#define	_NPCM	11
 #define	_NPCPV	677
 #define	_NPAD	1
 #else
 #error Unsupported page size
 #endif
+#define	_NPCM	howmany(_NPCPV, 64)
 
 #define	PV_CHUNK_HEADER							\
 	pmap_t			pc_pmap;				\