Skip to content

Commit 914cde5

Browse files
Quentin PerretMarc Zyngier
authored andcommitted
KVM: arm64: Remove list_head from hyp_page
The list_head member of struct hyp_page is only needed when the page is attached to a free-list, which by definition implies the page is free. As such, nothing prevents us from using the page itself to store the list_head, hence reducing the size of the vmemmap. Signed-off-by: Quentin Perret <qperret@google.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20210608114518.748712-4-qperret@google.com
1 parent 581982d commit 914cde5

2 files changed

Lines changed: 33 additions & 7 deletions

File tree

arch/arm64/kvm/hyp/include/nvhe/memory.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ struct hyp_page {
1212
unsigned int refcount;
1313
unsigned int order;
1414
struct hyp_pool *pool;
15-
struct list_head node;
1615
};
1716

1817
extern u64 __hyp_vmemmap;

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

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,34 @@ static struct hyp_page *__find_buddy_avail(struct hyp_pool *pool,
6262

6363
}
6464

65+
/*
66+
* Pages that are available for allocation are tracked in free-lists, so we use
67+
* the pages themselves to store the list nodes to avoid wasting space. As the
68+
* allocator always returns zeroed pages (which are zeroed on the hyp_put_page()
69+
* path to optimize allocation speed), we also need to clean-up the list node in
70+
* each page when we take it out of the list.
71+
*/
72+
static inline void page_remove_from_list(struct hyp_page *p)
73+
{
74+
struct list_head *node = hyp_page_to_virt(p);
75+
76+
__list_del_entry(node);
77+
memset(node, 0, sizeof(*node));
78+
}
79+
80+
static inline void page_add_to_list(struct hyp_page *p, struct list_head *head)
81+
{
82+
struct list_head *node = hyp_page_to_virt(p);
83+
84+
INIT_LIST_HEAD(node);
85+
list_add_tail(node, head);
86+
}
87+
88+
static inline struct hyp_page *node_to_page(struct list_head *node)
89+
{
90+
return hyp_virt_to_page(node);
91+
}
92+
6593
static void __hyp_attach_page(struct hyp_pool *pool,
6694
struct hyp_page *p)
6795
{
@@ -83,14 +111,14 @@ static void __hyp_attach_page(struct hyp_pool *pool,
83111
break;
84112

85113
/* Take the buddy out of its list, and coallesce with @p */
86-
list_del_init(&buddy->node);
114+
page_remove_from_list(buddy);
87115
buddy->order = HYP_NO_ORDER;
88116
p = min(p, buddy);
89117
}
90118

91119
/* Mark the new head, and insert it */
92120
p->order = order;
93-
list_add_tail(&p->node, &pool->free_area[order]);
121+
page_add_to_list(p, &pool->free_area[order]);
94122
}
95123

96124
static struct hyp_page *__hyp_extract_page(struct hyp_pool *pool,
@@ -99,7 +127,7 @@ static struct hyp_page *__hyp_extract_page(struct hyp_pool *pool,
99127
{
100128
struct hyp_page *buddy;
101129

102-
list_del_init(&p->node);
130+
page_remove_from_list(p);
103131
while (p->order > order) {
104132
/*
105133
* The buddy of order n - 1 currently has HYP_NO_ORDER as it
@@ -110,7 +138,7 @@ static struct hyp_page *__hyp_extract_page(struct hyp_pool *pool,
110138
p->order--;
111139
buddy = __find_buddy_nocheck(pool, p, p->order);
112140
buddy->order = p->order;
113-
list_add_tail(&buddy->node, &pool->free_area[buddy->order]);
141+
page_add_to_list(buddy, &pool->free_area[buddy->order]);
114142
}
115143

116144
return p;
@@ -182,7 +210,7 @@ void *hyp_alloc_pages(struct hyp_pool *pool, unsigned int order)
182210
}
183211

184212
/* Extract it from the tree at the right order */
185-
p = list_first_entry(&pool->free_area[i], struct hyp_page, node);
213+
p = node_to_page(pool->free_area[i].next);
186214
p = __hyp_extract_page(pool, p, order);
187215

188216
hyp_set_page_refcounted(p);
@@ -210,7 +238,6 @@ int hyp_pool_init(struct hyp_pool *pool, u64 pfn, unsigned int nr_pages,
210238
for (i = 0; i < nr_pages; i++) {
211239
p[i].pool = pool;
212240
p[i].order = 0;
213-
INIT_LIST_HEAD(&p[i].node);
214241
hyp_set_page_refcounted(&p[i]);
215242
}
216243

0 commit comments

Comments
 (0)