[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Add the support of x2apic logical cluster mode.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1252309606 -3600 # Node ID 9c84d25e6d88738164ea08814d801ff806277bbb # Parent cb249398f3eff1560b2a4934b0da08ec6b355eba Add the support of x2apic logical cluster mode. Add a xen boolean parameter 'x2apic'. Add a xen boolean parameter 'x2apic_phys'(by default, we use logical cluster mode). Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx> --- xen/arch/x86/apic.c | 35 ++++++++++++++++------- xen/arch/x86/genapic/x2apic.c | 62 +++++++++++++++++++++++++++++++++++------- xen/include/asm-x86/genapic.h | 31 +++++++++++++++------ 3 files changed, 100 insertions(+), 28 deletions(-) diff -r cb249398f3ef -r 9c84d25e6d88 xen/arch/x86/apic.c --- a/xen/arch/x86/apic.c Mon Sep 07 08:46:03 2009 +0100 +++ b/xen/arch/x86/apic.c Mon Sep 07 08:46:46 2009 +0100 @@ -848,8 +848,31 @@ void enable_x2apic(void) { u32 lo, hi; - if ( !iommu_supports_eim() ) - return; + if ( smp_processor_id() == 0 ) + { + if ( !iommu_supports_eim() ) + { + printk("x2APIC would not be enabled without EIM.\n"); + return; + } + + if ( apic_x2apic_phys.probe() ) + genapic = &apic_x2apic_phys; + else if ( apic_x2apic_cluster.probe() ) + genapic = &apic_x2apic_cluster; + else + { + printk("x2APIC would not be enabled due to x2apic=off.\n"); + return; + } + + x2apic_enabled = 1; + printk("Switched to APIC driver %s.\n", genapic->name); + } + else + { + BUG_ON(!x2apic_enabled); /* APs only enable x2apic when BSP did so. */ + } rdmsr(MSR_IA32_APICBASE, lo, hi); if ( !(lo & MSR_IA32_APICBASE_EXTD) ) @@ -860,14 +883,6 @@ void enable_x2apic(void) } else printk("x2APIC mode enabled by BIOS.\n"); - - if ( !x2apic_enabled ) - { - x2apic_enabled = 1; - genapic = &apic_x2apic; - printk(KERN_INFO "Switched to APIC driver %s.\n", - genapic->name); - } } void __init init_apic_mappings(void) diff -r cb249398f3ef -r 9c84d25e6d88 xen/arch/x86/genapic/x2apic.c --- a/xen/arch/x86/genapic/x2apic.c Mon Sep 07 08:46:03 2009 +0100 +++ b/xen/arch/x86/genapic/x2apic.c Mon Sep 07 08:46:46 2009 +0100 @@ -23,25 +23,46 @@ #include <xen/smp.h> #include <asm/mach-default/mach_mpparse.h> -__init int probe_x2apic(void) +static int x2apic = 1; +boolean_param("x2apic", x2apic); + +static int x2apic_phys = 0; /* By default we use logical cluster mode. */ +boolean_param("x2apic_phys", x2apic_phys); + +__init int probe_x2apic_phys(void) { - return x2apic_is_available(); + return x2apic && x2apic_phys && x2apic_is_available() && + iommu_supports_eim(); } -struct genapic apic_x2apic= { - APIC_INIT("x2apic", probe_x2apic), - GENAPIC_X2APIC +__init int probe_x2apic_cluster(void) +{ + return x2apic && !x2apic_phys && x2apic_is_available() && + iommu_supports_eim(); +} + +struct genapic apic_x2apic_phys= { + APIC_INIT("x2apic_phys", probe_x2apic_phys), + GENAPIC_X2APIC_PHYS }; -void init_apic_ldr_x2apic(void) +struct genapic apic_x2apic_cluster= { + APIC_INIT("x2apic_cluster", probe_x2apic_cluster), + GENAPIC_X2APIC_CLUSTER +}; + +void init_apic_ldr_x2apic_phys(void) { - /* We only use physical delivery mode. */ return; } +void init_apic_ldr_x2apic_cluster(void) +{ + int cpu = smp_processor_id(); + cpu_2_logical_apicid[cpu] = apic_read(APIC_LDR); +} void clustered_apic_check_x2apic(void) { - /* We only use physical delivery mode. */ return; } @@ -55,12 +76,17 @@ cpumask_t vector_allocation_domain_x2api return cpumask_of_cpu(cpu); } -unsigned int cpu_mask_to_apicid_x2apic(cpumask_t cpumask) +unsigned int cpu_mask_to_apicid_x2apic_phys(cpumask_t cpumask) { return cpu_physical_id(first_cpu(cpumask)); } -void send_IPI_mask_x2apic(const cpumask_t *cpumask, int vector) +unsigned int cpu_mask_to_apicid_x2apic_cluster(cpumask_t cpumask) +{ + return cpu_2_logical_apicid[first_cpu(cpumask)]; +} + +void send_IPI_mask_x2apic_phys(const cpumask_t *cpumask, int vector) { unsigned int cpu, cfg; unsigned long flags; @@ -87,3 +113,19 @@ void send_IPI_mask_x2apic(const cpumask_ local_irq_restore(flags); } +void send_IPI_mask_x2apic_cluster(const cpumask_t *cpumask, int vector) +{ + unsigned int cpu, cfg; + unsigned long flags; + + mb(); /* see the comment in send_IPI_mask_x2apic_phys() */ + + local_irq_save(flags); + + cfg = APIC_DM_FIXED | 0 /* no shorthand */ | APIC_DEST_LOGICAL | vector; + for_each_cpu_mask ( cpu, *cpumask ) + if ( cpu != smp_processor_id() ) + apic_wrmsr(APIC_ICR, cfg, cpu_2_logical_apicid[cpu]); + + local_irq_restore(flags); +} diff -r cb249398f3ef -r 9c84d25e6d88 xen/include/asm-x86/genapic.h --- a/xen/include/asm-x86/genapic.h Mon Sep 07 08:46:03 2009 +0100 +++ b/xen/include/asm-x86/genapic.h Mon Sep 07 08:46:46 2009 +0100 @@ -49,7 +49,8 @@ struct genapic { APICFUNC(acpi_madt_oem_check) extern struct genapic *genapic; -extern struct genapic apic_x2apic; +extern struct genapic apic_x2apic_phys; +extern struct genapic apic_x2apic_cluster; void init_apic_ldr_flat(void); void clustered_apic_check_flat(void); @@ -69,23 +70,37 @@ cpumask_t vector_allocation_domain_flat( .send_IPI_mask = send_IPI_mask_flat, \ .send_IPI_self = send_IPI_self_flat -void init_apic_ldr_x2apic(void); +void init_apic_ldr_x2apic_phys(void); +void init_apic_ldr_x2apic_cluster(void); void clustered_apic_check_x2apic(void); cpumask_t target_cpus_x2apic(void); -unsigned int cpu_mask_to_apicid_x2apic(cpumask_t cpumask); -void send_IPI_mask_x2apic(const cpumask_t *mask, int vector); +unsigned int cpu_mask_to_apicid_x2apic_phys(cpumask_t cpumask); +unsigned int cpu_mask_to_apicid_x2apic_cluster(cpumask_t cpumask); +void send_IPI_mask_x2apic_phys(const cpumask_t *mask, int vector); +void send_IPI_mask_x2apic_cluster(const cpumask_t *mask, int vector); void send_IPI_self_x2apic(int vector); cpumask_t vector_allocation_domain_x2apic(int cpu); -#define GENAPIC_X2APIC \ +#define GENAPIC_X2APIC_PHYS \ .int_delivery_mode = dest_Fixed, \ .int_dest_mode = 0 /* physical delivery */, \ - .init_apic_ldr = init_apic_ldr_x2apic, \ + .init_apic_ldr = init_apic_ldr_x2apic_phys, \ .clustered_apic_check = clustered_apic_check_x2apic, \ .target_cpus = target_cpus_x2apic, \ .vector_allocation_domain = vector_allocation_domain_x2apic, \ - .cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic, \ - .send_IPI_mask = send_IPI_mask_x2apic, \ + .cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic_phys, \ + .send_IPI_mask = send_IPI_mask_x2apic_phys, \ .send_IPI_self = send_IPI_self_x2apic + +#define GENAPIC_X2APIC_CLUSTER \ + .int_delivery_mode = dest_LowestPrio, \ + .int_dest_mode = 1 /* logical delivery */, \ + .init_apic_ldr = init_apic_ldr_x2apic_cluster, \ + .clustered_apic_check = clustered_apic_check_x2apic, \ + .target_cpus = target_cpus_x2apic, \ + .vector_allocation_domain = vector_allocation_domain_x2apic, \ + .cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic_cluster, \ + .send_IPI_mask = send_IPI_mask_x2apic_cluster, \ + .send_IPI_self = send_IPI_self_x2apic void init_apic_ldr_phys(void); void clustered_apic_check_phys(void); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |