mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/arm: optimize the size of struct vcpu
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, the vgic member of NEW_VGIC's struct vgic_cpu member private_irqs is changed to a pointer to struct vgic_irq. 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. As struct vcpu now fits into one page, drop MAX_PAGES_PER_VCPU. 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> Acked-by: Michal Orzel <michal.orzel@amd.com>
This commit is contained in:
1 parent
474e0d7493
commit
b7d3accd92
3 files changed
+12
-20
No files matched your search
+4
-19
@@ -473,36 +473,21 @@ void dump_pageframe_info(struct domain *d)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* The new VGIC has a bigger per-IRQ structure, so we need more than one
|
||||
* page on ARM64. Cowardly increase the limit in this case.
|
||||
*/
|
||||
#if defined(CONFIG_NEW_VGIC) && defined(CONFIG_ARM_64)
|
||||
#define MAX_PAGES_PER_VCPU 2
|
||||
#else
|
||||
#define MAX_PAGES_PER_VCPU 1
|
||||
#endif
|
||||
|
||||
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_page();
|
||||
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;
|
||||
}
|
||||
|
||||
void free_vcpu_struct(struct vcpu *v)
|
||||
{
|
||||
free_xenheap_pages(v, get_order_from_bytes(sizeof(*v)));
|
||||
free_xenheap_page(v);
|
||||
}
|
||||
|
||||
int arch_vcpu_create(struct vcpu *v)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||