Skip to content

Commit 581982d

Browse files
Quentin PerretMarc Zyngier
authored andcommitted
KVM: arm64: Use refcount at hyp to check page availability
The hyp buddy allocator currently checks the struct hyp_page list node to see if a page is available for allocation or not when trying to coalesce memory. Now that decrementing the refcount and attaching to the buddy tree is done in the same critical section, we can rely on the refcount of the buddy page to be in sync, which allows to replace the list node check by a refcount check. This will ease removing the list node from struct hyp_page later on. Signed-off-by: Quentin Perret <qperret@google.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20210608114518.748712-3-qperret@google.com
1 parent 6cbf874 commit 581982d

1 file changed

Lines changed: 11 additions & 5 deletions

File tree

arch/arm64/kvm/hyp/nvhe/page_alloc.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static struct hyp_page *__find_buddy_avail(struct hyp_pool *pool,
5555
{
5656
struct hyp_page *buddy = __find_buddy_nocheck(pool, p, order);
5757

58-
if (!buddy || buddy->order != order || list_empty(&buddy->node))
58+
if (!buddy || buddy->order != order || buddy->refcount)
5959
return NULL;
6060

6161
return buddy;
@@ -133,6 +133,12 @@ static inline void hyp_set_page_refcounted(struct hyp_page *p)
133133
p->refcount = 1;
134134
}
135135

136+
static void __hyp_put_page(struct hyp_pool *pool, struct hyp_page *p)
137+
{
138+
if (hyp_page_ref_dec_and_test(p))
139+
__hyp_attach_page(pool, p);
140+
}
141+
136142
/*
137143
* Changes to the buddy tree and page refcounts must be done with the hyp_pool
138144
* lock held. If a refcount change requires an update to the buddy tree (e.g.
@@ -146,8 +152,7 @@ void hyp_put_page(void *addr)
146152
struct hyp_pool *pool = hyp_page_to_pool(p);
147153

148154
hyp_spin_lock(&pool->lock);
149-
if (hyp_page_ref_dec_and_test(p))
150-
__hyp_attach_page(pool, p);
155+
__hyp_put_page(pool, p);
151156
hyp_spin_unlock(&pool->lock);
152157
}
153158

@@ -202,15 +207,16 @@ int hyp_pool_init(struct hyp_pool *pool, u64 pfn, unsigned int nr_pages,
202207

203208
/* Init the vmemmap portion */
204209
p = hyp_phys_to_page(phys);
205-
memset(p, 0, sizeof(*p) * nr_pages);
206210
for (i = 0; i < nr_pages; i++) {
207211
p[i].pool = pool;
212+
p[i].order = 0;
208213
INIT_LIST_HEAD(&p[i].node);
214+
hyp_set_page_refcounted(&p[i]);
209215
}
210216

211217
/* Attach the unused pages to the buddy tree */
212218
for (i = reserved_pages; i < nr_pages; i++)
213-
__hyp_attach_page(pool, &p[i]);
219+
__hyp_put_page(pool, &p[i]);
214220

215221
return 0;
216222
}

0 commit comments

Comments
 (0)