aboutsummaryrefslogtreecommitdiff
path: root/sys/arm64
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2018-06-23 10:41:52 +0000
committerMark Johnston <markj@FreeBSD.org>2018-06-23 10:41:52 +0000
commita8be239d697c4a3d4ffc59a3f5da516e7dee3772 (patch)
tree4c18c3da435aee64292763c0fa9cdf18b51312a4 /sys/arm64
parent63b5557b2f3556363ce7757010ce991d0933c624 (diff)
downloadsrc-a8be239d697c4a3d4ffc59a3f5da516e7dee3772.tar.gz
src-a8be239d697c4a3d4ffc59a3f5da516e7dee3772.zip
Re-count available PV entries after reclaiming a PV chunk.
The call to reclaim_pv_chunk() in reserve_pv_entries() may free a PV chunk with free entries belonging to the current pmap. In this case we must account for the free entries that were reclaimed, or reserve_pv_entries() may return without having reserved the requested number of entries. Reviewed by: alc, kib Tested by: pho (previous version) MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D15911
Notes
Notes: svn path=/head/; revision=335580
Diffstat (limited to 'sys/arm64')
-rw-r--r--sys/arm64/arm64/pmap.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index f4c0c4fe59bc..29724f17ef0a 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -2083,8 +2083,9 @@ reserve_pv_entries(pmap_t pmap, int needed, struct rwlock **lockp)
{
struct pch new_tail;
struct pv_chunk *pc;
- int avail, free;
vm_page_t m;
+ int avail, free;
+ bool reclaimed;
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
KASSERT(lockp != NULL, ("reserve_pv_entries: lockp is NULL"));
@@ -2107,13 +2108,14 @@ retry:
if (avail >= needed)
break;
}
- for (; avail < needed; avail += _NPCPV) {
+ for (reclaimed = false; avail < needed; avail += _NPCPV) {
m = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ |
VM_ALLOC_WIRED);
if (m == NULL) {
m = reclaim_pv_chunk(pmap, lockp);
if (m == NULL)
goto retry;
+ reclaimed = true;
}
PV_STAT(atomic_add_int(&pc_chunk_count, 1));
PV_STAT(atomic_add_int(&pc_chunk_allocs, 1));
@@ -2126,6 +2128,14 @@ retry:
TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc, pc_list);
TAILQ_INSERT_TAIL(&new_tail, pc, pc_lru);
PV_STAT(atomic_add_int(&pv_entry_spare, _NPCPV));
+
+ /*
+ * The reclaim might have freed a chunk from the current pmap.
+ * If that chunk contained available entries, we need to
+ * re-count the number of available entries.
+ */
+ if (reclaimed)
+ goto retry;
}
if (!TAILQ_EMPTY(&new_tail)) {
mtx_lock(&pv_chunks_mutex);