[PATCH v4 2/4] xen/arm: optimize the size of struct vcpu

Oleksii Kurochko posted 4 patches 2 weeks, 1 day ago
There is a newer version of this series
[PATCH v4 2/4] xen/arm: optimize the size of struct vcpu
Posted by Oleksii Kurochko 2 weeks, 1 day ago
When CONFIG_NEW_VGIC=y and CONFIG_ARM_64=y, the size of struct vcpu
exceeds one page, which requires allocating two pages and led to the
introduction of MAX_PAGES_PER_VCPU.

To remove the need for MAX_PAGES_PER_VCPU in a follow-up patch, the vgic
member of NEW_VGIC's struct vgic_vcpu member private_irq is changed to a
pointer to struct vgic_irq.
As a result, the size of struct vcpu for Arm64 is reduced to 2176 bytes,
compared to 3840 bytes (without these changes and with CONFIG_ARM_64=y)
and 4736 bytes (without these changes and with both CONFIG_ARM_64=y and
CONFIG_NEW_VGIC=y).

Since the private_irqs member is now a pointer, vcpu_vgic_init() and
vcpu_vgic_free() are updated to allocate and free private_irqs instance.

Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
Change in v4:
 - Add Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>.
---
Changes in v3:
 - Make private_irqs member as pointer to vgic_irq in struct vgic_cpu
   of new_vgic instead of vgic member of arch_vcpu.
---
Changes in v2:
 - New patch.
---
 xen/arch/arm/include/asm/new_vgic.h | 2 +-
 xen/arch/arm/vgic/vgic-init.c       | 7 +++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/xen/arch/arm/include/asm/new_vgic.h b/xen/arch/arm/include/asm/new_vgic.h
index 1e762138939f..6f7af0e02b2b 100644
--- a/xen/arch/arm/include/asm/new_vgic.h
+++ b/xen/arch/arm/include/asm/new_vgic.h
@@ -155,7 +155,7 @@ struct vgic_dist {
 };
 
 struct vgic_cpu {
-    struct vgic_irq private_irqs[VGIC_NR_PRIVATE_IRQS];
+    struct vgic_irq *private_irqs;
 
     struct list_head ap_list_head;
     spinlock_t ap_list_lock;    /* Protects the ap_list */
diff --git a/xen/arch/arm/vgic/vgic-init.c b/xen/arch/arm/vgic/vgic-init.c
index aef526f2e717..4eb49d922492 100644
--- a/xen/arch/arm/vgic/vgic-init.c
+++ b/xen/arch/arm/vgic/vgic-init.c
@@ -202,6 +202,11 @@ int vcpu_vgic_init(struct vcpu *v)
 {
     int ret = 0;
 
+    v->arch.vgic.private_irqs =
+        xzalloc_array(struct vgic_irq, VGIC_NR_PRIVATE_IRQS);
+    if ( !v->arch.vgic.private_irqs )
+        return -ENOMEM;
+
     vgic_vcpu_early_init(v);
 
     if ( gic_hw_version() == GIC_V2 )
@@ -244,6 +249,8 @@ void vcpu_vgic_free(struct vcpu *v)
     struct vgic_cpu *vgic_cpu = &v->arch.vgic;
 
     INIT_LIST_HEAD(&vgic_cpu->ap_list_head);
+
+    XFREE(v->arch.vgic.private_irqs);
 }
 
 /*
-- 
2.52.0
Re: [PATCH v4 2/4] xen/arm: optimize the size of struct vcpu
Posted by Orzel, Michal 1 week, 3 days ago

On 23/12/2025 18:01, Oleksii Kurochko wrote:
> When CONFIG_NEW_VGIC=y and CONFIG_ARM_64=y, the size of struct vcpu
> exceeds one page, which requires allocating two pages and led to the
> introduction of MAX_PAGES_PER_VCPU.
> 
> To remove the need for MAX_PAGES_PER_VCPU in a follow-up patch, the vgic
> member of NEW_VGIC's struct vgic_vcpu member private_irq is changed to a
s/vgic_vcpu/vgic_cpu/
s/private_irq/private_irqs/

> pointer to struct vgic_irq.
> As a result, the size of struct vcpu for Arm64 is reduced to 2176 bytes,
> compared to 3840 bytes (without these changes and with CONFIG_ARM_64=y)
> and 4736 bytes (without these changes and with both CONFIG_ARM_64=y and
> CONFIG_NEW_VGIC=y).
You only touch new vGIC, so there should be no size reduction without it but the
paragraph reads as if the change affected both old and new vGIC. Also I would
mention that probably you provided the numbers based on a defconfig target.

> 
> Since the private_irqs member is now a pointer, vcpu_vgic_init() and
> vcpu_vgic_free() are updated to allocate and free private_irqs instance.
> 
> Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Other than that:
Acked-by: Michal Orzel <michal.orzel@amd.com>

~Michal
Re: [PATCH v4 2/4] xen/arm: optimize the size of struct vcpu
Posted by Oleksii Kurochko 1 week, 1 day ago
On 12/29/25 12:08 PM, Orzel, Michal wrote:
>
> On 23/12/2025 18:01, Oleksii Kurochko wrote:
>> When CONFIG_NEW_VGIC=y and CONFIG_ARM_64=y, the size of struct vcpu
>> exceeds one page, which requires allocating two pages and led to the
>> introduction of MAX_PAGES_PER_VCPU.
>>
>> To remove the need for MAX_PAGES_PER_VCPU in a follow-up patch, the vgic
>> member of NEW_VGIC's struct vgic_vcpu member private_irq is changed to a
> s/vgic_vcpu/vgic_cpu/
> s/private_irq/private_irqs/
>
>> pointer to struct vgic_irq.
>> As a result, the size of struct vcpu for Arm64 is reduced to 2176 bytes,
>> compared to 3840 bytes (without these changes and with CONFIG_ARM_64=y)
>> and 4736 bytes (without these changes and with both CONFIG_ARM_64=y and
>> CONFIG_NEW_VGIC=y).
> You only touch new vGIC, so there should be no size reduction without it but the
> paragraph reads as if the change affected both old and new vGIC. Also I would
> mention that probably you provided the numbers based on a defconfig target.

   Yes, all the numbers are provided based on defconfig target.
   I will update this paragraph in the following way to be more clear:
   As a result, the size of struct vcpu for Arm64 is reduced to 2176 bytes
   in the case when CONFIG_ARM_64=y and CONFIG_NEW_VGIC=y, compared to 3840
   bytes (without these changes and with CONFIG_ARM_64=y) and 4736 bytes
   (without these changes and with both CONFIG_ARM_64=y and CONFIG_NEW_VGIC=y).
   Note that all numbers are based on defconfig with the mentioned options
   enabled or disabled as specified.

>
>> Since the private_irqs member is now a pointer, vcpu_vgic_init() and
>> vcpu_vgic_free() are updated to allocate and free private_irqs instance.
>>
>> Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
>> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Other than that:
> Acked-by: Michal Orzel <michal.orzel@amd.com>

Thanks!

~ Oleksii
Re: [PATCH v4 2/4] xen/arm: optimize the size of struct vcpu
Posted by Orzel, Michal 1 week, 3 days ago

On 29/12/2025 12:08, Orzel, Michal wrote:
> 
> 
> On 23/12/2025 18:01, Oleksii Kurochko wrote:
>> When CONFIG_NEW_VGIC=y and CONFIG_ARM_64=y, the size of struct vcpu
>> exceeds one page, which requires allocating two pages and led to the
>> introduction of MAX_PAGES_PER_VCPU.
Also, I think it would be better to drop MAX_PAGES_PER_VCPU in this patch.

~Michal

>>
>> To remove the need for MAX_PAGES_PER_VCPU in a follow-up patch, the vgic
>> member of NEW_VGIC's struct vgic_vcpu member private_irq is changed to a
> s/vgic_vcpu/vgic_cpu/
> s/private_irq/private_irqs/
> 
>> pointer to struct vgic_irq.
>> As a result, the size of struct vcpu for Arm64 is reduced to 2176 bytes,
>> compared to 3840 bytes (without these changes and with CONFIG_ARM_64=y)
>> and 4736 bytes (without these changes and with both CONFIG_ARM_64=y and
>> CONFIG_NEW_VGIC=y).
> You only touch new vGIC, so there should be no size reduction without it but the
> paragraph reads as if the change affected both old and new vGIC. Also I would
> mention that probably you provided the numbers based on a defconfig target.
> 
>>
>> Since the private_irqs member is now a pointer, vcpu_vgic_init() and
>> vcpu_vgic_free() are updated to allocate and free private_irqs instance.
>>
>> Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
>> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Other than that:
> Acked-by: Michal Orzel <michal.orzel@amd.com>
> 
> ~Michal
> 
>
Re: [PATCH v4 2/4] xen/arm: optimize the size of struct vcpu
Posted by Oleksii Kurochko 1 week, 1 day ago
On 12/29/25 12:10 PM, Orzel, Michal wrote:
>
> On 29/12/2025 12:08, Orzel, Michal wrote:
>>
>> On 23/12/2025 18:01, Oleksii Kurochko wrote:
>>> When CONFIG_NEW_VGIC=y and CONFIG_ARM_64=y, the size of struct vcpu
>>> exceeds one page, which requires allocating two pages and led to the
>>> introduction of MAX_PAGES_PER_VCPU.
> Also, I think it would be better to drop MAX_PAGES_PER_VCPU in this patch.

Then I'll update alloc_vcpu_struct() and free_vcpu_struct() to:
  struct vcpu *alloc_vcpu_struct(const struct domain *d)
  {
      struct vcpu *v;
  
-    BUILD_BUG_ON(sizeof(*v) > MAX_PAGES_PER_VCPU * PAGE_SIZE);
-    v = alloc_xenheap_pages(get_order_from_bytes(sizeof(*v)), 0);
+    BUILD_BUG_ON(sizeof(*v) > PAGE_SIZE);
+    v = alloc_xenheap_pages(0, 0);
      if ( v != NULL )
-    {
-        unsigned int i;
-
-        for ( i = 0; i < DIV_ROUND_UP(sizeof(*v), PAGE_SIZE); i++ )
-            clear_page((void *)v + i * PAGE_SIZE);
-    }
+        clear_page(v);
  
      return v;
@@ -503,5 +488,5 @@ struct vcpu *alloc_vcpu_struct(const struct domain *d)
  void free_vcpu_struct(struct vcpu *v)
  {
-    free_xenheap_pages(v, get_order_from_bytes(sizeof(*v)));
+    free_xenheap_page(v);
  }

Thanks.

~ Oleksii
Re: [PATCH v4 2/4] xen/arm: optimize the size of struct vcpu
Posted by Jan Beulich 2 days, 21 hours ago
On 31.12.2025 09:27, Oleksii Kurochko wrote:
> On 12/29/25 12:10 PM, Orzel, Michal wrote:
>> On 29/12/2025 12:08, Orzel, Michal wrote:
>>> On 23/12/2025 18:01, Oleksii Kurochko wrote:
>>>> When CONFIG_NEW_VGIC=y and CONFIG_ARM_64=y, the size of struct vcpu
>>>> exceeds one page, which requires allocating two pages and led to the
>>>> introduction of MAX_PAGES_PER_VCPU.
>> Also, I think it would be better to drop MAX_PAGES_PER_VCPU in this patch.
> 
> Then I'll update alloc_vcpu_struct() and free_vcpu_struct() to:
>   struct vcpu *alloc_vcpu_struct(const struct domain *d)
>   {
>       struct vcpu *v;
>   
> -    BUILD_BUG_ON(sizeof(*v) > MAX_PAGES_PER_VCPU * PAGE_SIZE);
> -    v = alloc_xenheap_pages(get_order_from_bytes(sizeof(*v)), 0);
> +    BUILD_BUG_ON(sizeof(*v) > PAGE_SIZE);
> +    v = alloc_xenheap_pages(0, 0);

Just one nit here: As (iirc) previously indicated by Andrew, please
avoid open-coding of alloc_xenheap_page().

Jan
Re: [PATCH v4 2/4] xen/arm: optimize the size of struct vcpu
Posted by Andrew Cooper 1 week, 3 days ago
On 29/12/2025 11:10 am, Orzel, Michal wrote:
>
> On 29/12/2025 12:08, Orzel, Michal wrote:
>>
>> On 23/12/2025 18:01, Oleksii Kurochko wrote:
>>> When CONFIG_NEW_VGIC=y and CONFIG_ARM_64=y, the size of struct vcpu
>>> exceeds one page, which requires allocating two pages and led to the
>>> introduction of MAX_PAGES_PER_VCPU.
> Also, I think it would be better to drop MAX_PAGES_PER_VCPU in this patch.

Or at least shrink it to just 1, which would be minimal churn.

>
> ~Michal
>
>>> To remove the need for MAX_PAGES_PER_VCPU in a follow-up patch, the vgic
>>> member of NEW_VGIC's struct vgic_vcpu member private_irq is changed to a
>> s/vgic_vcpu/vgic_cpu/
>> s/private_irq/private_irqs/
>>
>>> pointer to struct vgic_irq.
>>> As a result, the size of struct vcpu for Arm64 is reduced to 2176 bytes,
>>> compared to 3840 bytes (without these changes and with CONFIG_ARM_64=y)
>>> and 4736 bytes (without these changes and with both CONFIG_ARM_64=y and
>>> CONFIG_NEW_VGIC=y).
>> You only touch new vGIC, so there should be no size reduction without it but the
>> paragraph reads as if the change affected both old and new vGIC. Also I would
>> mention that probably you provided the numbers based on a defconfig target.

I think that was stale from v1, where this patch was far larger and more
invasive.

~Andrew