aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2022-08-17 19:10:12 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2022-08-17 19:10:12 +0000
commit5567d6b4419b02a2099527228b1a51cc55a5b47d (patch)
tree0fb13e385876ab729318565b88b85e044e8e453a
parente7d02be19d40063783d6b8f1ff2bc4c7170fd434 (diff)
downloadsrc-5567d6b4419b02a2099527228b1a51cc55a5b47d.tar.gz
src-5567d6b4419b02a2099527228b1a51cc55a5b47d.zip
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
-rw-r--r--sys/arm64/arm64/pmap.c30
-rw-r--r--sys/arm64/include/pmap.h3
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; \