[RFC PATCH 07/19] xen/domain: Alloc enough pages for VCPU struct

Mykyta Poturai posted 19 patches 1 week ago
[RFC PATCH 07/19] xen/domain: Alloc enough pages for VCPU struct
Posted by Mykyta Poturai 1 week ago
With introduction of GICv4 the size of struct vcpu can again be more
than one page. Modify struct vcpu allocation to request enough pages
again.

Don't reintroduce the MAX_PAGES_PER_VCPU check.
As per commit b77d774d8274183c2252f5fbc9fa3b3b7022ba06
> It turns out that beyond efficiency, maybe, there is no real technical
> reason this struct has to fit in one page

Since there is no technical reason to limit struct vcpu size to one page,
there also seems to be little reason the fiddle with 1 or 2 page limits.

Signed-off-by: Mykyta Poturai <mykyta_poturai@epam.com>
---
 xen/common/domain.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/xen/common/domain.c b/xen/common/domain.c
index 376351b528..c791fb5033 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -342,18 +342,24 @@ static struct vcpu *alloc_vcpu_struct(const struct domain *d)
 # define arch_vcpu_struct_memflags(d) ((void)(d), 0)
 #endif
     struct vcpu *v;
+    unsigned int order = get_order_from_bytes(sizeof(*v));
 
-    BUILD_BUG_ON(sizeof(*v) > PAGE_SIZE);
-    v = alloc_xenheap_pages(0, arch_vcpu_struct_memflags(d));
+    v = alloc_xenheap_pages(order, arch_vcpu_struct_memflags(d));
     if ( v )
-        clear_page(v);
+    {
+        unsigned int i;
+
+        for ( i = 0; i < DIV_ROUND_UP(sizeof(*v), PAGE_SIZE); i++ )
+            clear_page((void *)v + i * PAGE_SIZE);
+    }
 
     return v;
 }
 
 static void free_vcpu_struct(struct vcpu *v)
 {
-    free_xenheap_page(v);
+    unsigned int order = get_order_from_bytes(sizeof(*v));
+    free_xenheap_pages(v, order);
 }
 
 static void vmtrace_free_buffer(struct vcpu *v)
-- 
2.51.2
Re: [RFC PATCH 07/19] xen/domain: Alloc enough pages for VCPU struct
Posted by Jan Beulich 1 week ago
On 02.02.2026 17:14, Mykyta Poturai wrote:
> With introduction of GICv4 the size of struct vcpu can again be more
> than one page. Modify struct vcpu allocation to request enough pages
> again.
> 
> Don't reintroduce the MAX_PAGES_PER_VCPU check.
> As per commit b77d774d8274183c2252f5fbc9fa3b3b7022ba06
>> It turns out that beyond efficiency, maybe, there is no real technical
>> reason this struct has to fit in one page
> 
> Since there is no technical reason to limit struct vcpu size to one page,
> there also seems to be little reason the fiddle with 1 or 2 page limits.

Before writing this, did you check the recent discussion around the Arm
side change going back to a single page, and the moving of this code to
common/? Any ...

> --- a/xen/common/domain.c
> +++ b/xen/common/domain.c
> @@ -342,18 +342,24 @@ static struct vcpu *alloc_vcpu_struct(const struct domain *d)
>  # define arch_vcpu_struct_memflags(d) ((void)(d), 0)
>  #endif
>      struct vcpu *v;
> +    unsigned int order = get_order_from_bytes(sizeof(*v));
>  
> -    BUILD_BUG_ON(sizeof(*v) > PAGE_SIZE);
> -    v = alloc_xenheap_pages(0, arch_vcpu_struct_memflags(d));
> +    v = alloc_xenheap_pages(order, arch_vcpu_struct_memflags(d));

... non-order-0 allocation is at risk of failing despite there being
ample memory available, if there's heavy fragmentation. I'm sorry, but
without a much better justification this gets a NAK from me.

Jan