diff options
| author | Len Brown <len.brown@intel.com> | 2004-07-14 07:39:55 -0400 |
|---|---|---|
| committer | Len Brown <lenb@dhcppc3.> | 2004-07-14 07:39:55 -0400 |
| commit | 25bf3b3ea93d26d798595fe7b4e51c671d8fc0c6 (patch) | |
| tree | 1c62a80fb3310109a500314fc94c5f87fd325a7e | |
| parent | 52fb97fa0cca1e3e1881eb0620299070d17bd1b2 (diff) | |
[ACPI] add SMP suport to processor driver (Venkatesh Pallipadi)
http://bugzilla.kernel.org/show_bug.cgi?id=2615
| -rw-r--r-- | arch/i386/kernel/acpi/boot.c | 7 | ||||
| -rw-r--r-- | arch/i386/kernel/cpu/cpufreq/acpi.c | 30 | ||||
| -rw-r--r-- | arch/i386/kernel/smpboot.c | 6 | ||||
| -rw-r--r-- | arch/ia64/kernel/acpi.c | 6 | ||||
| -rw-r--r-- | arch/x86_64/kernel/smpboot.c | 1 | ||||
| -rw-r--r-- | drivers/acpi/processor.c | 65 | ||||
| -rw-r--r-- | include/asm-i386/acpi.h | 2 | ||||
| -rw-r--r-- | include/asm-i386/smp.h | 1 | ||||
| -rw-r--r-- | include/asm-ia64/acpi.h | 2 | ||||
| -rw-r--r-- | include/asm-x86_64/acpi.h | 2 |
10 files changed, 107 insertions, 15 deletions
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 99b1be964765..e179f4a906ae 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -83,6 +83,11 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; #warning ACPI uses CMPXCHG, i486 and later hardware #endif +#define MAX_MADT_ENTRIES 256 +u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] = + { [0 ... MAX_MADT_ENTRIES-1] = 0xff }; +EXPORT_SYMBOL(x86_acpiid_to_apicid); + /* -------------------------------------------------------------------------- Boot-time Configuration -------------------------------------------------------------------------- */ @@ -224,6 +229,8 @@ acpi_parse_lapic ( if (processor->flags.enabled == 0) return 0; + x86_acpiid_to_apicid[processor->acpi_id] = processor->id; + mp_register_lapic ( processor->id, /* APIC ID */ processor->flags.enabled); /* Enabled? */ diff --git a/arch/i386/kernel/cpu/cpufreq/acpi.c b/arch/i386/kernel/cpu/cpufreq/acpi.c index 8c056882df27..8c56687f071b 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi.c @@ -108,13 +108,27 @@ acpi_processor_set_performance ( u32 value = 0; int i = 0; struct cpufreq_freqs cpufreq_freqs; + cpumask_t saved_mask; + int retval; ACPI_FUNCTION_TRACE("acpi_processor_set_performance"); + /* + * TBD: Use something other than set_cpus_allowed. + * As set_cpus_allowed is a bit racy, + * with any other set_cpus_allowed for this process. + */ + saved_mask = current->cpus_allowed; + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + if (smp_processor_id() != cpu) { + return_VALUE(-EAGAIN); + } + if (state == data->acpi_data.state) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Already at target state (P%d)\n", state)); - return_VALUE(0); + retval = 0; + goto migrate_end; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n", @@ -144,7 +158,8 @@ acpi_processor_set_performance ( if (ret) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid port width 0x%04x\n", bit_width)); - return_VALUE(ret); + retval = ret; + goto migrate_end; } /* @@ -166,7 +181,8 @@ acpi_processor_set_performance ( if (ret) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid port width 0x%04x\n", bit_width)); - return_VALUE(ret); + retval = ret; + goto migrate_end; } if (value == (u32) data->acpi_data.states[state].status) break; @@ -183,7 +199,8 @@ acpi_processor_set_performance ( cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Transition failed\n")); - return_VALUE(-ENODEV); + retval = -ENODEV; + goto migrate_end; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -192,7 +209,10 @@ acpi_processor_set_performance ( data->acpi_data.state = state; - return_VALUE(0); + retval = 0; +migrate_end: + set_cpus_allowed(current, saved_mask); + return_VALUE(retval); } diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 45e8fbab361c..14406e35e79c 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -73,6 +73,10 @@ static cpumask_t smp_commenced_mask; /* Per CPU bogomips and other parameters */ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; +u8 x86_cpu_to_apicid[NR_CPUS] = + { [0 ... NR_CPUS-1] = 0xff }; +EXPORT_SYMBOL(x86_cpu_to_apicid); + /* Set when the idlers are all forked */ int smp_threads_ready; @@ -871,6 +875,7 @@ static int __init do_boot_cpu(int apicid) inquire_remote_apic(apicid); } } + x86_cpu_to_apicid[cpu] = apicid; if (boot_error) { /* Try to put things back the way they were before ... */ unmap_cpu_to_logical_apicid(cpu); @@ -953,6 +958,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); boot_cpu_logical_apicid = logical_smp_processor_id(); + x86_cpu_to_apicid[0] = boot_cpu_physical_apicid; current_thread_info()->cpu = 0; smp_tune_scheduling(); diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 28264441b3fb..560e6945cd76 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -65,6 +65,11 @@ void (*pm_power_off) (void); unsigned char acpi_kbd_controller_present = 1; unsigned char acpi_legacy_devices; +#define MAX_SAPICS 256 +u16 ia64_acpiid_to_sapicid[MAX_SAPICS] = + { [0 ... MAX_SAPICS - 1] = -1 }; +EXPORT_SYMBOL(ia64_acpiid_to_sapicid); + const char * acpi_get_sysname (void) { @@ -205,6 +210,7 @@ acpi_parse_lsapic (acpi_table_entry_header *header, const unsigned long end) == (unsigned int) smp_boot_data.cpu_phys_id[available_cpus]) printk(" (BSP)"); #endif + ia64_acpiid_to_sapicid[lsapic->acpi_id] = (lsapic->id << 8) | lsapic->eid; ++available_cpus; } diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index ba2cba68da14..20193af1b013 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -62,6 +62,7 @@ cpumask_t cpu_online_map; /* which logical CPU number maps to which CPU (physical APIC ID) */ volatile char x86_cpu_to_apicid[NR_CPUS]; +EXPORT_SYMBOL(x86_cpu_to_apicid); static cpumask_t cpu_callin_map; cpumask_t cpu_callout_map; diff --git a/drivers/acpi/processor.c b/drivers/acpi/processor.c index 38e13a1a9098..627135287d71 100644 --- a/drivers/acpi/processor.c +++ b/drivers/acpi/processor.c @@ -44,6 +44,9 @@ #include <asm/system.h> #include <asm/delay.h> #include <asm/uaccess.h> +#include <asm/processor.h> +#include <asm/smp.h> +#include <asm/acpi.h> #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> @@ -859,7 +862,6 @@ static void acpi_processor_ppc_exit(void) { * _PCT and _PSS structures are read out and written into struct * acpi_processor_performance. */ - static int acpi_processor_set_pdc (struct acpi_processor *pr) { acpi_status status = AE_OK; @@ -2146,6 +2148,37 @@ acpi_processor_remove_fs ( return_VALUE(0); } +/* Use the acpiid in MADT to map cpus in case of SMP */ +#ifndef CONFIG_SMP +#define convert_acpiid_to_cpu(acpi_id) (0xff) +#else + +#ifdef CONFIG_IA64 +#define arch_acpiid_to_apicid ia64_acpiid_to_sapicid +#define arch_cpu_to_apicid ia64_cpu_to_sapicid +#define ARCH_BAD_APICID (0xffff) +#else +#define arch_acpiid_to_apicid x86_acpiid_to_apicid +#define arch_cpu_to_apicid x86_cpu_to_apicid +#define ARCH_BAD_APICID (0xff) +#endif + +static u8 convert_acpiid_to_cpu(u8 acpi_id) +{ + u16 apic_id; + int i; + + apic_id = arch_acpiid_to_apicid[acpi_id]; + if (apic_id == ARCH_BAD_APICID) + return -1; + + for (i = 0; i < NR_CPUS; i++) { + if (arch_cpu_to_apicid[i] == apic_id) + return i; + } + return -1; +} +#endif /* -------------------------------------------------------------------------- Driver Interface @@ -2158,7 +2191,8 @@ acpi_processor_get_info ( acpi_status status = 0; union acpi_object object = {0}; struct acpi_buffer buffer = {sizeof(union acpi_object), &object}; - static int cpu_index = 0; + u8 cpu_index; + static int cpu0_initialized; ACPI_FUNCTION_TRACE("acpi_processor_get_info"); @@ -2168,13 +2202,6 @@ acpi_processor_get_info ( if (num_online_cpus() > 1) errata.smp = TRUE; - /* - * Extra Processor objects may be enumerated on MP systems with - * less than the max # of CPUs. They should be ignored. - */ - if ((cpu_index + 1) > num_online_cpus()) - return_VALUE(-ENODEV); - acpi_processor_errata(pr); /* @@ -2206,9 +2233,27 @@ acpi_processor_get_info ( * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c */ - pr->id = cpu_index++; pr->acpi_id = object.processor.proc_id; + cpu_index = convert_acpiid_to_cpu(pr->acpi_id); + + if ( !cpu0_initialized && (cpu_index == 0xff)) { + /* Handle UP system running SMP kernel, with no LAPIC in MADT */ + cpu_index = 0; + } else if (cpu_index > num_online_cpus()) { + /* + * Extra Processor objects may be enumerated on MP systems with + * less than the max # of CPUs. They should be ignored. + */ + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error getting cpuindex for acpiid 0x%x\n", + pr->acpi_id)); + return_VALUE(-ENODEV); + } + cpu0_initialized = 1; + + pr->id = cpu_index; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, pr->acpi_id)); diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h index 42164a6d5fe0..ce1852636faa 100644 --- a/include/asm-i386/acpi.h +++ b/include/asm-i386/acpi.h @@ -178,6 +178,8 @@ extern void acpi_reserve_bootmem(void); #endif /*CONFIG_ACPI_SLEEP*/ +extern u8 x86_acpiid_to_apicid[]; + #endif /*__KERNEL__*/ #endif /*_ASM_ACPI_H*/ diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index 88c461e5e107..ba7eccc97f19 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h @@ -43,6 +43,7 @@ extern void (*mtrr_hook) (void); extern void zap_low_mappings (void); #define MAX_APICID 256 +extern u8 x86_cpu_to_apicid[]; /* * This function is needed by all SMP systems. It must _always_ be valid diff --git a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h index 3e13984cf871..1ebe9a591227 100644 --- a/include/asm-ia64/acpi.h +++ b/include/asm-ia64/acpi.h @@ -105,6 +105,8 @@ extern int __initdata pxm_to_nid_map[MAX_PXM_DOMAINS]; extern int __initdata nid_to_pxm_map[MAX_NUMNODES]; #endif +extern u16 ia64_acpiid_to_sapicid[]; + #endif /*__KERNEL__*/ #endif /*_ASM_ACPI_H*/ diff --git a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h index b768ed272d72..3ebe9be2aea9 100644 --- a/include/asm-x86_64/acpi.h +++ b/include/asm-x86_64/acpi.h @@ -163,6 +163,8 @@ extern int acpi_pci_disabled; #define BROKEN_ACPI_Sx 0x0001 #define BROKEN_INIT_AFTER_S1 0x0002 +extern u8 x86_acpiid_to_apicid[]; + #endif /*__KERNEL__*/ #endif /*_ASM_ACPI_H*/ |
