aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64/amd64/pmap.c
diff options
context:
space:
mode:
authorAlan Cox <alc@FreeBSD.org>2012-04-06 16:41:19 +0000
committerAlan Cox <alc@FreeBSD.org>2012-04-06 16:41:19 +0000
commit3e4c7bf65aa7b817484c49fbf5bd4609356bb2b9 (patch)
tree9c7ebaacbb23f27b0829e91d9efeab2681a84393 /sys/amd64/amd64/pmap.c
parent57bd5cce62f14e6f40c5679c0e20c4705f924157 (diff)
downloadsrc-3e4c7bf65aa7b817484c49fbf5bd4609356bb2b9.tar.gz
src-3e4c7bf65aa7b817484c49fbf5bd4609356bb2b9.zip
Micro-optimize free_pv_entry() for the expected case.
Notes
Notes: svn path=/head/; revision=233954
Diffstat (limited to 'sys/amd64/amd64/pmap.c')
-rw-r--r--sys/amd64/amd64/pmap.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index f293aaf1c251..ff4f96ba330f 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -2095,7 +2095,6 @@ pmap_collect(pmap_t locked_pmap, struct vpgqueues *vpq)
}
}
-
/*
* free the pv_entry back to the free list
*/
@@ -2116,13 +2115,16 @@ free_pv_entry(pmap_t pmap, pv_entry_t pv)
field = idx / 64;
bit = idx % 64;
pc->pc_map[field] |= 1ul << bit;
- /* move to head of list */
- TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
if (pc->pc_map[0] != PC_FREE0 || pc->pc_map[1] != PC_FREE1 ||
pc->pc_map[2] != PC_FREE2) {
- TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc, pc_list);
+ /* 98% of the time, pc is already at the head of the list. */
+ if (__predict_false(pc != TAILQ_FIRST(&pmap->pm_pvchunk))) {
+ TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
+ TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc, pc_list);
+ }
return;
}
+ TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
PV_STAT(pv_entry_spare -= _NPCPV);
PV_STAT(pc_chunk_count--);
PV_STAT(pc_chunk_frees++);