From patchwork Tue Dec 3 16:39:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanjun Guo X-Patchwork-Id: 21983 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ie0-f199.google.com (mail-ie0-f199.google.com [209.85.223.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id AFB48202AE for ; Tue, 3 Dec 2013 16:40:01 +0000 (UTC) Received: by mail-ie0-f199.google.com with SMTP id lx4sf47400012iec.10 for ; Tue, 03 Dec 2013 08:40:01 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=rjDK/Yi43sWVFq7G510d/Wn9GFfxONM1tiVnukwqLas=; b=Wtjp38qMihSvUzLljv35ks2Mu6Cnc+stJOZ6YYyPOFF82Gb7sg1I5GHPy2IQcja1C9 eQNCYTfZM5jKE2hmCy5dfZZMLkoAtf67np2+H6T5emX33e4/G/J6VGjeN/DX4c5mHHlV hN06eGfoXwhL8koiZPjajfRBaIMWYt7eWsnr+z7UL7LxHcUR/6dKCwVFYHDibkrx1wWB B0lPHeVfaBRw5AsLgrJ6qDfxGJ9mAfaeqPsec0tE8xm+q4yaldZ8J/d971TuEzebsd2H 7rCQj0tinv6QBGWBIR9G7BPULjPYC7oABous+dO/HlS7owQhzfBKY5snIMwLSQlew+QN OTdw== X-Gm-Message-State: ALoCoQlgXn3r+gjl9/o2pNJeDb7fH4gD5AXuS5aBQw+YFXIspuvetaB+UGSSA5Gq/NaLIDtETLxe X-Received: by 10.42.65.138 with SMTP id l10mr867256ici.31.1386088801084; Tue, 03 Dec 2013 08:40:01 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.83.2 with SMTP id m2ls1890074qey.37.gmail; Tue, 03 Dec 2013 08:40:01 -0800 (PST) X-Received: by 10.221.29.200 with SMTP id rz8mr2034109vcb.33.1386088800967; Tue, 03 Dec 2013 08:40:00 -0800 (PST) Received: from mail-vc0-f175.google.com (mail-vc0-f175.google.com [209.85.220.175]) by mx.google.com with ESMTPS id tj6si31560473vcb.118.2013.12.03.08.40.00 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 03 Dec 2013 08:40:00 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.175 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.175; Received: by mail-vc0-f175.google.com with SMTP id ld13so9893337vcb.20 for ; Tue, 03 Dec 2013 08:40:00 -0800 (PST) X-Received: by 10.52.117.176 with SMTP id kf16mr7975316vdb.6.1386088800789; Tue, 03 Dec 2013 08:40:00 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp222556vcz; Tue, 3 Dec 2013 08:40:00 -0800 (PST) X-Received: by 10.69.31.1 with SMTP id ki1mr39732079pbd.124.1386088799898; Tue, 03 Dec 2013 08:39:59 -0800 (PST) Received: from mail-pb0-f44.google.com (mail-pb0-f44.google.com [209.85.160.44]) by mx.google.com with ESMTPS id ts1si14781887pbc.140.2013.12.03.08.39.59 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 03 Dec 2013 08:39:59 -0800 (PST) Received-SPF: neutral (google.com: 209.85.160.44 is neither permitted nor denied by best guess record for domain of hanjun.guo@linaro.org) client-ip=209.85.160.44; Received: by mail-pb0-f44.google.com with SMTP id rq2so21374563pbb.17 for ; Tue, 03 Dec 2013 08:39:59 -0800 (PST) X-Received: by 10.68.178.197 with SMTP id da5mr39722560pbc.28.1386088799430; Tue, 03 Dec 2013 08:39:59 -0800 (PST) Received: from localhost ([219.142.3.202]) by mx.google.com with ESMTPSA id ql10sm131154306pbc.44.2013.12.03.08.39.50 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 03 Dec 2013 08:39:58 -0800 (PST) From: Hanjun Guo To: "Rafael J. Wysocki" , Catalin Marinas , Will Deacon , Russell King - ARM Linux , Daniel Lezcano Cc: linux-acpi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Grant Likely , Matthew Garrett , Olof Johansson , Linus Walleij , Bjorn Helgaas , Rob Herring , Mark Rutland , Jon Masters , patches@linaro.org, linux-kernel@vger.kernel.org, linaro-kernel@lists.linaro.org, linaro-acpi@lists.linaro.org, Hanjun Guo Subject: [RFC part2 PATCH 2/9] ARM64 / ACPI: Prefill cpu possible/present maps and map logical cpu id to APIC id Date: Wed, 4 Dec 2013 00:39:06 +0800 Message-Id: <1386088753-2850-3-git-send-email-hanjun.guo@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1386088753-2850-1-git-send-email-hanjun.guo@linaro.org> References: <1386088753-2850-1-git-send-email-hanjun.guo@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: hanjun.guo@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.175 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , When boot the kernel with MADT, the cpu possible and present maps should be prefilled for cpu topology and acpi based cpu hot-plug. The logic cpu id maps to APIC id (GIC id) is also implemented, it is needed for acpi processor drivers. Signed-off-by: Hanjun Guo --- arch/arm64/include/asm/acpi.h | 10 ++-- arch/arm64/kernel/setup.c | 2 + arch/arm64/kernel/smp.c | 2 + drivers/acpi/plat/arm-core.c | 118 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h index be2951c..423a32c 100644 --- a/arch/arm64/include/asm/acpi.h +++ b/arch/arm64/include/asm/acpi.h @@ -76,9 +76,6 @@ static inline void acpi_disable_pci(void) /* FIXME: this function should be moved to topology.h when it's ready */ void arch_fix_phys_package_id(int num, u32 slot); -/* temperally define -1 to make acpi core compilerable */ -#define cpu_physical_id(cpu) -1 - /* Low-level suspend routine. */ extern int (*acpi_suspend_lowlevel)(void); #define acpi_wakeup_address (0) @@ -86,6 +83,13 @@ extern int (*acpi_suspend_lowlevel)(void); #define MAX_GIC_CPU_INTERFACE 256 #define MAX_GIC_DISTRIBUTOR 1 /* should be the same as MAX_GIC_NR */ +/* map logic cpu id to physical GIC id */ +extern int arm_cpu_to_apicid[NR_CPUS]; +extern int boot_cpu_apic_id; +#define cpu_physical_id(cpu) arm_cpu_to_apicid[cpu] + +extern void prefill_possible_map(void); + #else /* !CONFIG_ACPI */ #define acpi_disabled 1 /* ACPI sometimes enabled on ARM */ #define acpi_noirq 1 /* ACPI sometimes enabled on ARM */ diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 8199360..08f11e2 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -231,7 +231,9 @@ void __init setup_arch(char **cmdline_p) */ acpi_boot_table_init(); early_acpi_boot_init(); + boot_cpu_apic_id = read_cpuid_mpidr() & MPIDR_HWID_BITMASK; acpi_boot_init(); + prefill_possible_map(); paging_init(); request_standard_resources(); diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index a0c2ca6..1428024 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -420,7 +420,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus) if (err) continue; +#ifndef CONFIG_ACPI set_cpu_present(cpu, true); +#endif max_cpus--; } } diff --git a/drivers/acpi/plat/arm-core.c b/drivers/acpi/plat/arm-core.c index 45ff625..8527ecc 100644 --- a/drivers/acpi/plat/arm-core.c +++ b/drivers/acpi/plat/arm-core.c @@ -58,6 +58,13 @@ EXPORT_SYMBOL(acpi_pci_disabled); */ static u64 acpi_lapic_addr __initdata; +/* available_cpus here means enabled cpu in MADT */ +int available_cpus; + +/* Map logic cpu id to physical GIC id. */ +int arm_cpu_to_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = -1 }; +int boot_cpu_apic_id = -1; + #define BAD_MADT_ENTRY(entry, end) ( \ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ ((struct acpi_subtable_header *)entry)->length < sizeof(*entry)) @@ -142,6 +149,39 @@ static int __init acpi_parse_madt(struct acpi_table_header *table) * Please refer to chapter5.2.12.14/15 of ACPI 5.0 */ +static void acpi_register_gic_cpu_interface(int id, u8 enabled) +{ + int cpu; + + if (id >= MAX_GIC_CPU_INTERFACE) { + pr_info(PREFIX "skipped apicid that is too big\n"); + return; + } + + total_cpus++; + if (!enabled) + return; + + available_cpus++; + + /* allocate a logic cpu id for the new comer */ + if (boot_cpu_apic_id == id) { + /* + * boot_cpu_init() already hold bit 0 in cpu_present_mask + * for BSP, no need to allocte again. + */ + cpu = 0; + } else { + cpu = cpumask_next_zero(-1, cpu_present_mask); + } + + /* map the logic cpu id to APIC id */ + arm_cpu_to_apicid[cpu] = id; + + set_cpu_present(cpu, true); + set_cpu_possible(cpu, true); +} + static int __init acpi_parse_gic(struct acpi_subtable_header *header, const unsigned long end) { @@ -154,6 +194,16 @@ acpi_parse_gic(struct acpi_subtable_header *header, const unsigned long end) acpi_table_print_madt_entry(header); + /* + * We need to register disabled CPU as well to permit + * counting disabled CPUs. This allows us to size + * cpus_possible_map more accurately, to permit + * to not preallocating memory for all NR_CPUS + * when we use CPU hotplug. + */ + acpi_register_gic_cpu_interface(processor->gic_id, + processor->flags & ACPI_MADT_ENABLED); + return 0; } @@ -196,6 +246,19 @@ static int __init acpi_parse_madt_gic_entries(void) return count; } +#ifdef CONFIG_SMP + if (available_cpus == 0) { + pr_info(PREFIX "Found 0 CPUs; assuming 1\n"); + /* FIXME: should be the real GIC id read from hardware */ + arm_cpu_to_apicid[available_cpus] = 0; + available_cpus = 1; /* We've got at least one of these */ + } +#endif + + /* Make boot-up look pretty */ + pr_info("%d CPUs available, %d CPUs total\n", available_cpus, + total_cpus); + return 0; } @@ -221,6 +284,61 @@ static int __init acpi_parse_madt_gic_distributor_entries(void) return 0; } +static int setup_possible_cpus __initdata = -1; +static int __init _setup_possible_cpus(char *str) +{ + get_option(&str, &setup_possible_cpus); + return 0; +} +early_param("possible_cpus", _setup_possible_cpus); + +/* + * cpu_possible_mask should be static, it cannot change as cpu's + * are onlined, or offlined. The reason is per-cpu data-structures + * are allocated by some modules at init time, and dont expect to + * do this dynamically on cpu arrival/departure. + * cpu_present_mask on the other hand can change dynamically. + * In case when cpu_hotplug is not compiled, then we resort to current + * behaviour, which is cpu_possible == cpu_present. + * - Ashok Raj + * + * Three ways to find out the number of additional hotplug CPUs: + * - If the BIOS specified disabled CPUs in ACPI/mptables use that. + * - The user can overwrite it with possible_cpus=NUM + * - Otherwise don't reserve additional CPUs. + * We do this because additional CPUs waste a lot of memory. + * -AK + */ +void __init prefill_possible_map(void) +{ + int i; + int possible, disabled_cpus; + + disabled_cpus = total_cpus - available_cpus; + + if (setup_possible_cpus == -1) { + if (disabled_cpus > 0) + setup_possible_cpus = disabled_cpus; + else + setup_possible_cpus = 0; + } + + possible = available_cpus + setup_possible_cpus; + + pr_info("SMP: the system is limited to %d CPUs\n", nr_cpu_ids); + + if (possible > nr_cpu_ids) + possible = nr_cpu_ids; + + pr_info("SMP: Allowing %d CPUs, %d hotplug CPUs\n", + possible, max((possible - available_cpus), 0)); + + for (i = 0; i < possible; i++) + set_cpu_possible(i, true); + for (; i < NR_CPUS; i++) + set_cpu_possible(i, false); +} + int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) { *irq = gsi_to_irq(gsi);