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
This commit is contained in:
John Baldwin 2022-08-17 12:10:12 -07:00
parent e7d02be19d
commit 5567d6b441
2 changed files with 14 additions and 19 deletions

View File

@ -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 @@ get_pv_entry(pmap_t pmap, struct rwlock **lockp)
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);
}

View File

@ -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; \