From patchwork Sat Oct 6 15:27:34 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiang Liu X-Patchwork-Id: 1558401 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 8E294DF238 for ; Sat, 6 Oct 2012 15:36:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754888Ab2JFPgT (ORCPT ); Sat, 6 Oct 2012 11:36:19 -0400 Received: from mail-pb0-f46.google.com ([209.85.160.46]:35570 "EHLO mail-pb0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754727Ab2JFPgP (ORCPT ); Sat, 6 Oct 2012 11:36:15 -0400 Received: by mail-pb0-f46.google.com with SMTP id rr4so2817710pbb.19 for ; Sat, 06 Oct 2012 08:36:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=c6ZBi0R3HnMr5PbYX3jM3tcCOYi8sbxC8hdiRsbCBTQ=; b=F1wMg4hSQ+tRFRtPVSEr19sPsyX/2hMzPrmb44cPqKBmwNwRq3J7ab+bi5UvFqYEDO gqfB26wW8Ms8n0Fzrn48BOWLUOdyMNBI+u2gH6VFeVQ2WqBojrU7mSTB1Qqv5zT3lDay C0CxjTmVIMMCIElXHHqix4fwfFGxrzQdWYGcImbLqDX36DF2+wSwPeSsAZe66vvPwtLM V5RU+cC/AV42c9fx0GWSap2CHP2OFvsVwAII6+Yi3i3gpMjVYQUUcV9fw5pfSREBjNrE xuIwvwLbI1hPQoo9mLjE0wcslr3nXjEEkblhLwm8tIU+VShAWBqnt3lxlBrjixjbJSu+ goZw== Received: by 10.68.141.46 with SMTP id rl14mr39499875pbb.2.1349537774421; Sat, 06 Oct 2012 08:36:14 -0700 (PDT) Received: from localhost.localdomain ([221.221.24.247]) by mx.google.com with ESMTPS id vz8sm7785292pbc.63.2012.10.06.08.35.59 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 06 Oct 2012 08:36:13 -0700 (PDT) From: Jiang Liu To: Yinghai Lu , Yasuaki Ishimatsu , Kenji Kaneshige , Wen Congyang , Tang Chen , Taku Izumi Cc: Hanjun Guo , Yijing Wang , Gong Chen , Jiang Liu , Tony Luck , Huang Ying , Bob Moore , Len Brown , "Srivatsa S . Bhat" , Bjorn Helgaas , linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-pci@vger.kernel.org Subject: [RFC PATCH v3 26/28] ACPI/processor: save parsed APIC ID in processor driver data structure Date: Sat, 6 Oct 2012 23:27:34 +0800 Message-Id: <1349537256-21670-27-git-send-email-jiang.liu@huawei.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1349537256-21670-1-git-send-email-jiang.liu@huawei.com> References: <1349537256-21670-1-git-send-email-jiang.liu@huawei.com> Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org Enhance ACPI processor driver to save parsed APIC ID in processor driver data structure, and avoid reparsing again in _acpi_map_lsapic(). This change also makes fake CPU hotplug possible because we have no dependency on _MAT method now. Signed-off-by: Jiang Liu --- arch/ia64/kernel/acpi.c | 38 ++++---------------------------------- arch/x86/kernel/acpi/boot.c | 38 +++----------------------------------- drivers/acpi/internal.h | 2 ++ drivers/acpi/processor_core.c | 26 +++++++++++++++++++++----- drivers/acpi/processor_driver.c | 15 +++++++++------ include/acpi/processor.h | 1 + include/linux/acpi.h | 2 +- 7 files changed, 41 insertions(+), 81 deletions(-) diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 44057885..f0da941 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -880,40 +880,10 @@ __init void prefill_possible_map(void) set_cpu_possible(i, true); } -static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) +static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) { - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - struct acpi_madt_local_sapic *lsapic; cpumask_t tmp_map; - int cpu, physid; - - if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) - return -EINVAL; - - if (!buffer.length || !buffer.pointer) - return -EINVAL; - - obj = buffer.pointer; - if (obj->type != ACPI_TYPE_BUFFER) - { - kfree(buffer.pointer); - return -EINVAL; - } - - lsapic = (struct acpi_madt_local_sapic *)obj->buffer.pointer; - - if ((lsapic->header.type != ACPI_MADT_TYPE_LOCAL_SAPIC) || - (!(lsapic->lapic_flags & ACPI_MADT_ENABLED))) { - kfree(buffer.pointer); - return -EINVAL; - } - - physid = ((lsapic->id << 8) | (lsapic->eid)); - - kfree(buffer.pointer); - buffer.length = ACPI_ALLOCATE_BUFFER; - buffer.pointer = NULL; + int cpu; cpumask_complement(&tmp_map, cpu_present_mask); cpu = cpumask_first(&tmp_map); @@ -932,9 +902,9 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) } /* wrapper to silence section mismatch warning */ -int __ref acpi_map_lsapic(acpi_handle handle, int *pcpu) +int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) { - return _acpi_map_lsapic(handle, pcpu); + return _acpi_map_lsapic(handle, physid, pcpu); } EXPORT_SYMBOL(acpi_map_lsapic); diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index e651f7a..5e76952 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -608,44 +608,12 @@ static void __cpuinit acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) #endif } -static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) +static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) { - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - struct acpi_madt_local_apic *lapic; cpumask_var_t tmp_map, new_map; - u8 physid; int cpu; int retval = -ENOMEM; - if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) - return -EINVAL; - - if (!buffer.length || !buffer.pointer) - return -EINVAL; - - obj = buffer.pointer; - if (obj->type != ACPI_TYPE_BUFFER || - obj->buffer.length < sizeof(*lapic)) { - kfree(buffer.pointer); - return -EINVAL; - } - - lapic = (struct acpi_madt_local_apic *)obj->buffer.pointer; - - if (lapic->header.type != ACPI_MADT_TYPE_LOCAL_APIC || - !(lapic->lapic_flags & ACPI_MADT_ENABLED)) { - kfree(buffer.pointer); - return -EINVAL; - } - - physid = lapic->id; - - kfree(buffer.pointer); - buffer.length = ACPI_ALLOCATE_BUFFER; - buffer.pointer = NULL; - lapic = NULL; - if (!alloc_cpumask_var(&tmp_map, GFP_KERNEL)) goto out; @@ -683,9 +651,9 @@ out: } /* wrapper to silence section mismatch warning */ -int __ref acpi_map_lsapic(acpi_handle handle, int *pcpu) +int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu) { - return _acpi_map_lsapic(handle, pcpu); + return _acpi_map_lsapic(handle, physid, pcpu); } EXPORT_SYMBOL(acpi_map_lsapic); diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 6f0632d..036dba11 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -47,6 +47,8 @@ int acpi_bus_init_power(struct acpi_device *device); int acpi_wakeup_device_init(void); void acpi_early_processor_set_pdc(void); +int acpi_get_apicid(acpi_handle handle, int type, u32 acpi_id); +int acpi_map_cpuid(int apic_id, u32 acpi_id); /* -------------------------------------------------------------------------- Embedded Controller diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index eff7222..21217e5 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -163,16 +163,23 @@ exit: return apic_id; } -int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) +int acpi_get_apicid(acpi_handle handle, int type, u32 acpi_id) { -#ifdef CONFIG_SMP - int i; -#endif - int apic_id = -1; + int apic_id; apic_id = map_mat_entry(handle, type, acpi_id); if (apic_id == -1) apic_id = map_madt_entry(type, acpi_id); + + return apic_id; +} + +int acpi_map_cpuid(int apic_id, u32 acpi_id) +{ +#ifdef CONFIG_SMP + int i; +#endif + if (apic_id == -1) { /* * On UP processor, there is no _MAT or MADT table. @@ -212,6 +219,15 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) #endif return -1; } + +int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) +{ + int apic_id; + + apic_id = acpi_get_apicid(handle, type, acpi_id); + + return acpi_map_cpuid(apic_id, acpi_id); +} EXPORT_SYMBOL_GPL(acpi_get_cpuid); static bool __init processor_physically_present(acpi_handle handle) diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 51e3993..2346b81 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -57,6 +57,7 @@ #include #include #include +#include "internal.h" #define PREFIX "ACPI: " @@ -303,7 +304,8 @@ static int acpi_processor_get_info(struct acpi_device *device) device_declaration = 1; pr->acpi_id = value; } - cpu_index = acpi_get_cpuid(pr->handle, device_declaration, pr->acpi_id); + pr->apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id); + cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); /* Handle UP system running SMP kernel, with no LAPIC in MADT */ if (!cpu0_initialized && (cpu_index == -1) && @@ -689,7 +691,7 @@ static int acpi_processor_get_dev_info(struct acpi_device *device, static int acpi_processor_pre_configure(struct acpi_device *device, struct acpihp_cancel_context *ctx) { - int result; + int result = -EINVAL; struct acpi_processor *pr; if (!device || !acpi_driver_data(device)) @@ -698,9 +700,11 @@ static int acpi_processor_pre_configure(struct acpi_device *device, /* Generate CPUID for hot-added CPUs */ if (pr->id == -1) { - result = acpi_map_lsapic(device->handle, &pr->id); + if (pr->apic_id == -1) + goto out; + result = acpi_map_lsapic(device->handle, pr->apic_id, &pr->id); if (result) - goto out_unlock; + goto out; BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); result = arch_register_cpu(pr->id, 1); if (result) @@ -720,8 +724,7 @@ static int acpi_processor_pre_configure(struct acpi_device *device, out_unmap: acpi_unmap_lsapic(pr->id); pr->id = -1; -out_unlock: - put_online_cpus(); +out: return result; } diff --git a/include/acpi/processor.h b/include/acpi/processor.h index ae7d94e..da65f1f 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -200,6 +200,7 @@ struct acpi_processor_flags { struct acpi_processor { acpi_handle handle; u32 acpi_id; + int apic_id; u32 id; u32 pblk; int performance_platform_limit; diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 90be989..774ce2b 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -101,7 +101,7 @@ void acpi_numa_arch_fixup(void); #ifdef CONFIG_ACPI_HOTPLUG_CPU /* Arch dependent functions for cpu hotplug support */ -int acpi_map_lsapic(acpi_handle handle, int *pcpu); +int acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu); int acpi_unmap_lsapic(int cpu); #endif /* CONFIG_ACPI_HOTPLUG_CPU */