aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/smpboot.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2011-10-13 10:02:34 +0200
committerJan Beulich <jbeulich@suse.com>2011-10-13 10:02:34 +0200
commitddbb942359ebec0d96a73a90495e0b29a19266f9 (patch)
treec24fa28224f59361af4d6738163c46772c8086bd /xen/arch/x86/smpboot.c
parentb569c46bb3153903d59f3eeefc19ee046dab75e0 (diff)
downloadxen-ddbb942359ebec0d96a73a90495e0b29a19266f9.tar.gz
xen-ddbb942359ebec0d96a73a90495e0b29a19266f9.tar.bz2
xen-ddbb942359ebec0d96a73a90495e0b29a19266f9.zip
x86-64: don't use xmalloc_array() for allocation of the (per-CPU) IDTs
The IDTs being exactly a page in size, using xmalloc() here is rather inefficient, as this requires double the amount to be allocated (with almost an entire page wasted). For hot plugged CPUs, this at once eliminates one more non-order-zero runtime allocation. For x86-32, however, the IDT is exactly half a page, so allocating a full page seems wasteful here, so it continues to use xmalloc() as before. With most of the affected functions' bodies now being inside #ifdef-s, it might be reasonable to split those parts out into subarch-specific code... Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/smpboot.c')
-rw-r--r--xen/arch/x86/smpboot.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index b49edb509a..6dd3b34959 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -639,9 +639,6 @@ static void cpu_smpboot_free(unsigned int cpu)
{
unsigned int order;
- xfree(idt_tables[cpu]);
- idt_tables[cpu] = NULL;
-
order = get_order_from_pages(NR_RESERVED_GDT_PAGES);
#ifdef __x86_64__
if ( per_cpu(compat_gdt_table, cpu) )
@@ -650,10 +647,15 @@ static void cpu_smpboot_free(unsigned int cpu)
free_domheap_pages(virt_to_page(per_cpu(compat_gdt_table, cpu)),
order);
per_cpu(compat_gdt_table, cpu) = NULL;
+ order = get_order_from_bytes(IDT_ENTRIES * sizeof(**idt_tables));
+ if ( idt_tables[cpu] )
+ free_domheap_pages(virt_to_page(idt_tables[cpu]), order);
#else
free_xenheap_pages(per_cpu(gdt_table, cpu), order);
+ xfree(idt_tables[cpu]);
#endif
per_cpu(gdt_table, cpu) = NULL;
+ idt_tables[cpu] = NULL;
if ( stack_base[cpu] != NULL )
{
@@ -691,19 +693,25 @@ static int cpu_smpboot_alloc(unsigned int cpu)
if ( !page )
goto oom;
per_cpu(gdt_table, cpu) = gdt = page_to_virt(page);
+ order = get_order_from_bytes(IDT_ENTRIES * sizeof(**idt_tables));
+ page = alloc_domheap_pages(NULL, order,
+ MEMF_node(cpu_to_node(cpu)));
+ if ( !page )
+ goto oom;
+ idt_tables[cpu] = page_to_virt(page);
#else
per_cpu(gdt_table, cpu) = gdt = alloc_xenheap_pages(order, 0);
if ( !gdt )
goto oom;
+ idt_tables[cpu] = xmalloc_array(idt_entry_t, IDT_ENTRIES);
+ if ( idt_tables[cpu] == NULL )
+ goto oom;
#endif
memcpy(gdt, boot_cpu_gdt_table,
NR_RESERVED_GDT_PAGES * PAGE_SIZE);
BUILD_BUG_ON(NR_CPUS > 0x10000);
gdt[PER_CPU_GDT_ENTRY - FIRST_RESERVED_GDT_ENTRY].a = cpu;
- idt_tables[cpu] = xmalloc_array(idt_entry_t, IDT_ENTRIES);
- if ( idt_tables[cpu] == NULL )
- goto oom;
memcpy(idt_tables[cpu], idt_table,
IDT_ENTRIES*sizeof(idt_entry_t));