Message ID | 20230216182043.1946553-11-sunilvl@ventanamicro.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp457056wrn; Thu, 16 Feb 2023 10:23:31 -0800 (PST) X-Google-Smtp-Source: AK7set8CAxfZaqrVZAZ3UMh5jI46GBEnAWyigbpfGryyxPX/x4QVyWhDEDEvxTb+Gu3zEmSD/jF4 X-Received: by 2002:a17:903:2306:b0:19a:a4fc:7f80 with SMTP id d6-20020a170903230600b0019aa4fc7f80mr7868793plh.26.1676571811671; Thu, 16 Feb 2023 10:23:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676571811; cv=none; d=google.com; s=arc-20160816; b=ImHZWa5C1umlf2NSsrSiqcOQ4qWiOqpxlrOTuuRGrdgfqoqUD2KpdzWpR5Po34iWi0 akfbagHsHEKxWrmFgToaSjwjueEQ0svUZnx8d78FnceOdAHG628j8L1A30beUeEYVJUZ MONu3oCAwZDcUiBXDv5DVTSdz4dez+g0UH8tZvD6EV/u7fGuetzzcUNgPSX1FoXCDxlg vTt9QCdarSgBTwUi9cfCVnU/Lx5vxygy2fAPF/iMTRCD8Q44VovZgiUvQSz+8FMN+Aaw Emfpa+Jic2akLfXZiUEkoN4mWhL/E1e2goKO3C4mdizEN+8CxCIhSFue0ty67WhV0gYv G+WQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=s8gLVy86DoWbnyaOmwt3yk4bIOk4obRTX8YOySNU6bM=; b=bAfO+kCBEa8/KJ2VoCd8dhvU2BvESzvn7C0IwOqERH39YububUpXzKU6AtlxTahEeX otzUXUc7Gokhee7/IxpKnCRR+aae2ODRnUmebMFenSl98q8MSv5wWHvvuH0tVGtMBMPB ZV+TkcEuPHVXOrhHzYyx70HEIG4z1PUPeX85UDMai6xsuAoYlZ0FrPsdMq29rIp6Z+u5 3aghVRoWJelxgIxB2WehwpRUYnqhDATi2SrLEbsjFiXD/NVWbNOdGeKkpGBtNdiICkVZ xjGTdCc5r7ZFOA9vvhbicjSrYgbBmiE7o7A1xKVi6xhZ9lgQXSMtUqtA9xDPOONrn8Rl gc9A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ventanamicro.com header.s=google header.b=VpdtjEii; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id a5-20020a170902710500b0019b007ce788si1390415pll.269.2023.02.16.10.23.18; Thu, 16 Feb 2023 10:23:31 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@ventanamicro.com header.s=google header.b=VpdtjEii; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230285AbjBPSWd (ORCPT <rfc822;aimixsaka@gmail.com> + 99 others); Thu, 16 Feb 2023 13:22:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56066 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230252AbjBPSWL (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 16 Feb 2023 13:22:11 -0500 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 722D32A15A for <linux-kernel@vger.kernel.org>; Thu, 16 Feb 2023 10:21:42 -0800 (PST) Received: by mail-pj1-x102c.google.com with SMTP id d2so2703229pjd.5 for <linux-kernel@vger.kernel.org>; Thu, 16 Feb 2023 10:21:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=s8gLVy86DoWbnyaOmwt3yk4bIOk4obRTX8YOySNU6bM=; b=VpdtjEii+t5cvC5ibTSbTwjU4Vx3GiWKkzTOXqXjUr0YDKlzh2RTmRhrfafw6GTtsc YTQqnR6kqj6GRIgl9yX/vR6IHxTBJo7vdDNEj8DswgI7MPqnnTKk6CnOzErmcN5CCH2b ZwMNZtNf6oZbN7d+YG/54CFyPCKr7rLx8eQKziHq+F0+XPYQXsrOqlge5KMGhUXVQVMo nT8fZ/aoGGnmZ86ZY/5kHh7e+61wbBNj1IkEy+Sk4r9srBbf2euRVlaJls3S5LTMegLN dC+DQ9pSlYuPW3W5SR4Zgw/zMM7vqJOQ/chaI5xf2TMznWD+BoyMvGkFM9XtER5brYcS 3B8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=s8gLVy86DoWbnyaOmwt3yk4bIOk4obRTX8YOySNU6bM=; b=X3R3YhtFHJK7KrE+lt8kx9dMceWYu42hO0fu30jfM0bKyrZg2Wkabd8rD5JLnVqy7f 4Xcn6eSnFDEQFOMyclKkJQLC52DVo+XjopQMwam4moL+wbfgoc2m1I4XWx27wJwF/4p6 q1cn0/QuG+fZzjdqIpjDMAahQBXfWUamUGHU7tawkjAzOVM0Hmts/Su+2kZznJEvUmZQ A2c5dQB2BMDQx3iCH+2T0lxKQUSFJoUdGWV/hlyKqflt+eBqzMCOj0UJzGlPRe9CJa0R ZxcYXSEgZiEyAFwwDZlP0EiOzWmukZ+I/zVyX1IM8sVTj5y8tDGAOtXhkLZBSzPy8De7 cIuw== X-Gm-Message-State: AO0yUKX+jJ9kd37t7meME/WX93yrwpWMIAzHExY4oyaXOIygX1cpb4LW 1NvRKYZ4hPjStekXPFZSFRzjLQ== X-Received: by 2002:a17:90b:1d87:b0:233:d4fd:38a3 with SMTP id pf7-20020a17090b1d8700b00233d4fd38a3mr7710027pjb.41.1676571700518; Thu, 16 Feb 2023 10:21:40 -0800 (PST) Received: from kerodi.Dlink ([49.206.14.226]) by smtp.gmail.com with ESMTPSA id n21-20020a637215000000b004dff15fc121sm1517574pgc.36.2023.02.16.10.21.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Feb 2023 10:21:40 -0800 (PST) From: Sunil V L <sunilvl@ventanamicro.com> To: Palmer Dabbelt <palmer@dabbelt.com>, Albert Ou <aou@eecs.berkeley.edu>, Paul Walmsley <paul.walmsley@sifive.com>, "Rafael J . Wysocki" <rafael@kernel.org>, Len Brown <lenb@kernel.org>, Thomas Gleixner <tglx@linutronix.de>, Marc Zyngier <maz@kernel.org>, Jonathan Corbet <corbet@lwn.net> Cc: linux-riscv@lists.infradead.org, linux-acpi@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Conor Dooley <conor.dooley@microchip.com>, Andrew Jones <ajones@ventanamicro.com>, Anup Patel <apatel@ventanamicro.com>, Atish Patra <atishp@rivosinc.com>, Sunil V L <sunilvl@ventanamicro.com>, "Rafael J . Wysocki" <rafael.j.wysocki@intel.com> Subject: [PATCH V2 10/21] RISC-V: smpboot: Add ACPI support in smp_setup() Date: Thu, 16 Feb 2023 23:50:32 +0530 Message-Id: <20230216182043.1946553-11-sunilvl@ventanamicro.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230216182043.1946553-1-sunilvl@ventanamicro.com> References: <20230216182043.1946553-1-sunilvl@ventanamicro.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1758012964023029861?= X-GMAIL-MSGID: =?utf-8?q?1758012964023029861?= |
Series |
Add basic ACPI support for RISC-V
|
|
Commit Message
Sunil V L
Feb. 16, 2023, 6:20 p.m. UTC
Enable SMP boot on ACPI based platforms by using the RINTC structures in the MADT table. Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Conor Dooley <conor.dooley@microchip.com> --- arch/riscv/include/asm/acpi.h | 7 ++++ arch/riscv/kernel/smpboot.c | 70 ++++++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 1 deletion(-)
Comments
On Thu, Feb 16, 2023 at 11:50:32PM +0530, Sunil V L wrote: > Enable SMP boot on ACPI based platforms by using the RINTC > structures in the MADT table. > > Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > Reviewed-by: Conor Dooley <conor.dooley@microchip.com> > --- > arch/riscv/include/asm/acpi.h | 7 ++++ > arch/riscv/kernel/smpboot.c | 70 ++++++++++++++++++++++++++++++++++- > 2 files changed, 76 insertions(+), 1 deletion(-) > > diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h > index 7bc49f65c86b..3c3a8ac3b37a 100644 > --- a/arch/riscv/include/asm/acpi.h > +++ b/arch/riscv/include/asm/acpi.h > @@ -60,6 +60,13 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { } > > int acpi_get_riscv_isa(struct acpi_table_header *table, > unsigned int cpu, const char **isa); > + > +#ifdef CONFIG_ACPI_NUMA > +int acpi_numa_get_nid(unsigned int cpu); > +#else > +static inline int acpi_numa_get_nid(unsigned int cpu) { return NUMA_NO_NODE; } > +#endif /* CONFIG_ACPI_NUMA */ The #ifdef stuff seems premature since we're not providing an implementation for acpi_numa_get_nid() or selecting ACPI_NUMA, but OK. > + > #else > static inline int acpi_get_riscv_isa(struct acpi_table_header *table, > unsigned int cpu, const char **isa) > diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c > index 26214ddefaa4..77630f8ed12b 100644 > --- a/arch/riscv/kernel/smpboot.c > +++ b/arch/riscv/kernel/smpboot.c > @@ -8,6 +8,7 @@ > * Copyright (C) 2017 SiFive > */ > > +#include <linux/acpi.h> > #include <linux/arch_topology.h> > #include <linux/module.h> > #include <linux/init.h> > @@ -70,6 +71,70 @@ void __init smp_prepare_cpus(unsigned int max_cpus) > } > } > > +#ifdef CONFIG_ACPI > +static unsigned int cpu_count = 1; > + > +static int __init acpi_parse_rintc(union acpi_subtable_headers *header, const unsigned long end) > +{ > + unsigned long hart; > + bool found_boot_cpu = false; I guess found_boot_cpu should be static? > + struct acpi_madt_rintc *processor = (struct acpi_madt_rintc *)header; > + > + /* > + * Each RINTC structure in MADT will have a flag. If ACPI_MADT_ENABLED > + * bit in the flag is not enabled, it means OS should not try to enable > + * the cpu to which RINTC belongs. > + */ > + if (!(processor->flags & ACPI_MADT_ENABLED)) > + return 0; > + > + hart = processor->hart_id; > + if (hart < 0) > + return 0; A valid hart ID is anything up to INVALID_HARTID, right? Shouldn't we only be checking for INVALID_HARTID here? And what does it mean to have an invalid hart ID here? It's not an issue to error/warn about? > + if (hart == cpuid_to_hartid_map(0)) { > + BUG_ON(found_boot_cpu); Do we really want to BUG due to bad, but potentially bootable ACPI tables? I'd BUG for things that can only happen when we break the code, but broken ACPI tables might be something we want to complain loudly about and then attempt to limp along. > + found_boot_cpu = true; > + early_map_cpu_to_node(0, acpi_numa_get_nid(cpu_count)); > + return 0; > + } > + > + if (cpu_count >= NR_CPUS) { > + pr_warn("Invalid cpuid [%d] for hartid [%lu]\n", > + cpu_count, hart); cpuid isn't invalid, NR_CPUS is too small for the number of ACPI tables. > + return 0; > + } > + > + cpuid_to_hartid_map(cpu_count) = hart; > + early_map_cpu_to_node(cpu_count, acpi_numa_get_nid(cpu_count)); > + cpu_count++; > + > + return 0; > +} > + > +static void __init acpi_parse_and_init_cpus(void) > +{ > + int cpuid; > + > + cpu_set_ops(0); > + > + /* > + * do a walk of MADT to determine how many CPUs > + * we have including disabled CPUs, and get information > + * we need for SMP init. > + */ I know this comment comes verbatim from arm64, but not only does it have grammar issues, I'm not sure it's accurate. Where is the count of disabled CPUs for arm64 or riscv? > + acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, acpi_parse_rintc, 0); > + > + for (cpuid = 1; cpuid < nr_cpu_ids; cpuid++) { > + if (cpuid_to_hartid_map(cpuid) != INVALID_HARTID) { > + cpu_set_ops(cpuid); > + set_cpu_possible(cpuid, true); > + } > + } > +} > +#else > +#define acpi_parse_and_init_cpus(...) do { } while (0) > +#endif > + > static void __init of_parse_and_init_cpus(void) > { > struct device_node *dn; > @@ -118,7 +183,10 @@ static void __init of_parse_and_init_cpus(void) > > void __init setup_smp(void) > { > - of_parse_and_init_cpus(); > + if (acpi_disabled) > + of_parse_and_init_cpus(); > + else > + acpi_parse_and_init_cpus(); > } > > static int start_secondary_cpu(int cpu, struct task_struct *tidle) > -- > 2.34.1 > Do we not want to add an entry to acpi_table_print_madt_entry() for RINTC? Thanks, drew
On Mon, Feb 20, 2023 at 06:08:43PM +0100, Andrew Jones wrote: > On Thu, Feb 16, 2023 at 11:50:32PM +0530, Sunil V L wrote: > > Enable SMP boot on ACPI based platforms by using the RINTC > > structures in the MADT table. > > > > Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> > > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > Reviewed-by: Conor Dooley <conor.dooley@microchip.com> > > --- > > arch/riscv/include/asm/acpi.h | 7 ++++ > > arch/riscv/kernel/smpboot.c | 70 ++++++++++++++++++++++++++++++++++- > > 2 files changed, 76 insertions(+), 1 deletion(-) > > > > diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h > > index 7bc49f65c86b..3c3a8ac3b37a 100644 > > --- a/arch/riscv/include/asm/acpi.h > > +++ b/arch/riscv/include/asm/acpi.h > > @@ -60,6 +60,13 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { } > > > > int acpi_get_riscv_isa(struct acpi_table_header *table, > > unsigned int cpu, const char **isa); > > + > > +#ifdef CONFIG_ACPI_NUMA > > +int acpi_numa_get_nid(unsigned int cpu); > > +#else > > +static inline int acpi_numa_get_nid(unsigned int cpu) { return NUMA_NO_NODE; } > > +#endif /* CONFIG_ACPI_NUMA */ > > The #ifdef stuff seems premature since we're not providing an > implementation for acpi_numa_get_nid() or selecting ACPI_NUMA, but OK. > Yes, will remove it. We can add as part NUMA enablement. > > + > > #else > > static inline int acpi_get_riscv_isa(struct acpi_table_header *table, > > unsigned int cpu, const char **isa) > > diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c > > index 26214ddefaa4..77630f8ed12b 100644 > > --- a/arch/riscv/kernel/smpboot.c > > +++ b/arch/riscv/kernel/smpboot.c > > @@ -8,6 +8,7 @@ > > * Copyright (C) 2017 SiFive > > */ > > > > +#include <linux/acpi.h> > > #include <linux/arch_topology.h> > > #include <linux/module.h> > > #include <linux/init.h> > > @@ -70,6 +71,70 @@ void __init smp_prepare_cpus(unsigned int max_cpus) > > } > > } > > > > +#ifdef CONFIG_ACPI > > +static unsigned int cpu_count = 1; > > + > > +static int __init acpi_parse_rintc(union acpi_subtable_headers *header, const unsigned long end) > > +{ > > + unsigned long hart; > > + bool found_boot_cpu = false; > > I guess found_boot_cpu should be static? > Good catch!. Thanks! > > + struct acpi_madt_rintc *processor = (struct acpi_madt_rintc *)header; > > + > > + /* > > + * Each RINTC structure in MADT will have a flag. If ACPI_MADT_ENABLED > > + * bit in the flag is not enabled, it means OS should not try to enable > > + * the cpu to which RINTC belongs. > > + */ > > + if (!(processor->flags & ACPI_MADT_ENABLED)) > > + return 0; > > + > > + hart = processor->hart_id; > > + if (hart < 0) > > + return 0; > > A valid hart ID is anything up to INVALID_HARTID, right? Shouldn't we only > be checking for INVALID_HARTID here? And what does it mean to have an > invalid hart ID here? It's not an issue to error/warn about? > Yes, will check for INVALID_HARTID (though I am not really sure how it can be invalid). Will add a warning. > > + if (hart == cpuid_to_hartid_map(0)) { > > + BUG_ON(found_boot_cpu); > > Do we really want to BUG due to bad, but potentially bootable ACPI tables? > I'd BUG for things that can only happen when we break the code, but broken > ACPI tables might be something we want to complain loudly about and then > attempt to limp along. > Okay. I used same logic as in DT. It may be better to use BUG instead of debugging weird symptoms later, right? > > + found_boot_cpu = true; > > + early_map_cpu_to_node(0, acpi_numa_get_nid(cpu_count)); > > + return 0; > > + } > > + > > + if (cpu_count >= NR_CPUS) { > > + pr_warn("Invalid cpuid [%d] for hartid [%lu]\n", > > + cpu_count, hart); > > cpuid isn't invalid, NR_CPUS is too small for the number of ACPI tables. > Okay. > > + return 0; > > + } > > + > > + cpuid_to_hartid_map(cpu_count) = hart; > > + early_map_cpu_to_node(cpu_count, acpi_numa_get_nid(cpu_count)); > > + cpu_count++; > > + > > + return 0; > > +} > > + > > +static void __init acpi_parse_and_init_cpus(void) > > +{ > > + int cpuid; > > + > > + cpu_set_ops(0); > > + > > + /* > > + * do a walk of MADT to determine how many CPUs > > + * we have including disabled CPUs, and get information > > + * we need for SMP init. > > + */ > > I know this comment comes verbatim from arm64, but not only does it > have grammar issues, I'm not sure it's accurate. Where is the count > of disabled CPUs for arm64 or riscv? > MADT will have multiple RINTC structures. Each RINTC structure will have a flag to indicate whether enabled or disabled. So, we need to walk the MADT to get all CPUs present. But I think this comment is not required since comments are added in the parser function. > > + acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, acpi_parse_rintc, 0); > > + > > + for (cpuid = 1; cpuid < nr_cpu_ids; cpuid++) { > > + if (cpuid_to_hartid_map(cpuid) != INVALID_HARTID) { > > + cpu_set_ops(cpuid); > > + set_cpu_possible(cpuid, true); > > + } > > + } > > +} > > +#else > > +#define acpi_parse_and_init_cpus(...) do { } while (0) > > +#endif > > + > > static void __init of_parse_and_init_cpus(void) > > { > > struct device_node *dn; > > @@ -118,7 +183,10 @@ static void __init of_parse_and_init_cpus(void) > > > > void __init setup_smp(void) > > { > > - of_parse_and_init_cpus(); > > + if (acpi_disabled) > > + of_parse_and_init_cpus(); > > + else > > + acpi_parse_and_init_cpus(); > > } > > > > static int start_secondary_cpu(int cpu, struct task_struct *tidle) > > -- > > 2.34.1 > > > > Do we not want to add an entry to acpi_table_print_madt_entry() for RINTC? > Yes. Will add a patch for this to help debugging. Thanks, Sunil
On Fri, Feb 24, 2023 at 10:20:17PM +0530, Sunil V L wrote: > On Mon, Feb 20, 2023 at 06:08:43PM +0100, Andrew Jones wrote: > > On Thu, Feb 16, 2023 at 11:50:32PM +0530, Sunil V L wrote: > > > Enable SMP boot on ACPI based platforms by using the RINTC > > > structures in the MADT table. > > > > > > Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> > > > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > > Reviewed-by: Conor Dooley <conor.dooley@microchip.com> > > > --- > > > arch/riscv/include/asm/acpi.h | 7 ++++ > > > arch/riscv/kernel/smpboot.c | 70 ++++++++++++++++++++++++++++++++++- > > > 2 files changed, 76 insertions(+), 1 deletion(-) > > > > > > diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h > > > index 7bc49f65c86b..3c3a8ac3b37a 100644 > > > --- a/arch/riscv/include/asm/acpi.h > > > +++ b/arch/riscv/include/asm/acpi.h > > > @@ -60,6 +60,13 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { } > > > > > > int acpi_get_riscv_isa(struct acpi_table_header *table, > > > unsigned int cpu, const char **isa); > > > + > > > +#ifdef CONFIG_ACPI_NUMA > > > +int acpi_numa_get_nid(unsigned int cpu); > > > +#else > > > +static inline int acpi_numa_get_nid(unsigned int cpu) { return NUMA_NO_NODE; } > > > +#endif /* CONFIG_ACPI_NUMA */ > > > > The #ifdef stuff seems premature since we're not providing an > > implementation for acpi_numa_get_nid() or selecting ACPI_NUMA, but OK. > > > Yes, will remove it. We can add as part NUMA enablement. > > > > + > > > #else > > > static inline int acpi_get_riscv_isa(struct acpi_table_header *table, > > > unsigned int cpu, const char **isa) > > > diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c > > > index 26214ddefaa4..77630f8ed12b 100644 > > > --- a/arch/riscv/kernel/smpboot.c > > > +++ b/arch/riscv/kernel/smpboot.c > > > @@ -8,6 +8,7 @@ > > > * Copyright (C) 2017 SiFive > > > */ > > > > > > +#include <linux/acpi.h> > > > #include <linux/arch_topology.h> > > > #include <linux/module.h> > > > #include <linux/init.h> > > > @@ -70,6 +71,70 @@ void __init smp_prepare_cpus(unsigned int max_cpus) > > > } > > > } > > > > > > +#ifdef CONFIG_ACPI > > > +static unsigned int cpu_count = 1; > > > + > > > +static int __init acpi_parse_rintc(union acpi_subtable_headers *header, const unsigned long end) > > > +{ > > > + unsigned long hart; > > > + bool found_boot_cpu = false; > > > > I guess found_boot_cpu should be static? > > > Good catch!. Thanks! > > > > + struct acpi_madt_rintc *processor = (struct acpi_madt_rintc *)header; > > > + > > > + /* > > > + * Each RINTC structure in MADT will have a flag. If ACPI_MADT_ENABLED > > > + * bit in the flag is not enabled, it means OS should not try to enable > > > + * the cpu to which RINTC belongs. > > > + */ > > > + if (!(processor->flags & ACPI_MADT_ENABLED)) > > > + return 0; > > > + > > > + hart = processor->hart_id; > > > + if (hart < 0) > > > + return 0; > > > > A valid hart ID is anything up to INVALID_HARTID, right? Shouldn't we only > > be checking for INVALID_HARTID here? And what does it mean to have an > > invalid hart ID here? It's not an issue to error/warn about? > > > Yes, will check for INVALID_HARTID (though I am not really sure how it > can be invalid). Will add a warning. > > > > + if (hart == cpuid_to_hartid_map(0)) { > > > + BUG_ON(found_boot_cpu); > > > > Do we really want to BUG due to bad, but potentially bootable ACPI tables? > > I'd BUG for things that can only happen when we break the code, but broken > > ACPI tables might be something we want to complain loudly about and then > > attempt to limp along. > > > Okay. I used same logic as in DT. It may be better to use BUG instead of > debugging weird symptoms later, right? Maybe? I guess it depends on how obvious the symptoms are, how much they mess things up, and how easy it is to correct the ACPI tables. I'll leave this one up to you :-) Thanks, drew
diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h index 7bc49f65c86b..3c3a8ac3b37a 100644 --- a/arch/riscv/include/asm/acpi.h +++ b/arch/riscv/include/asm/acpi.h @@ -60,6 +60,13 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) { } int acpi_get_riscv_isa(struct acpi_table_header *table, unsigned int cpu, const char **isa); + +#ifdef CONFIG_ACPI_NUMA +int acpi_numa_get_nid(unsigned int cpu); +#else +static inline int acpi_numa_get_nid(unsigned int cpu) { return NUMA_NO_NODE; } +#endif /* CONFIG_ACPI_NUMA */ + #else static inline int acpi_get_riscv_isa(struct acpi_table_header *table, unsigned int cpu, const char **isa) diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index 26214ddefaa4..77630f8ed12b 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -8,6 +8,7 @@ * Copyright (C) 2017 SiFive */ +#include <linux/acpi.h> #include <linux/arch_topology.h> #include <linux/module.h> #include <linux/init.h> @@ -70,6 +71,70 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } } +#ifdef CONFIG_ACPI +static unsigned int cpu_count = 1; + +static int __init acpi_parse_rintc(union acpi_subtable_headers *header, const unsigned long end) +{ + unsigned long hart; + bool found_boot_cpu = false; + struct acpi_madt_rintc *processor = (struct acpi_madt_rintc *)header; + + /* + * Each RINTC structure in MADT will have a flag. If ACPI_MADT_ENABLED + * bit in the flag is not enabled, it means OS should not try to enable + * the cpu to which RINTC belongs. + */ + if (!(processor->flags & ACPI_MADT_ENABLED)) + return 0; + + hart = processor->hart_id; + if (hart < 0) + return 0; + if (hart == cpuid_to_hartid_map(0)) { + BUG_ON(found_boot_cpu); + found_boot_cpu = true; + early_map_cpu_to_node(0, acpi_numa_get_nid(cpu_count)); + return 0; + } + + if (cpu_count >= NR_CPUS) { + pr_warn("Invalid cpuid [%d] for hartid [%lu]\n", + cpu_count, hart); + return 0; + } + + cpuid_to_hartid_map(cpu_count) = hart; + early_map_cpu_to_node(cpu_count, acpi_numa_get_nid(cpu_count)); + cpu_count++; + + return 0; +} + +static void __init acpi_parse_and_init_cpus(void) +{ + int cpuid; + + cpu_set_ops(0); + + /* + * do a walk of MADT to determine how many CPUs + * we have including disabled CPUs, and get information + * we need for SMP init. + */ + acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, acpi_parse_rintc, 0); + + for (cpuid = 1; cpuid < nr_cpu_ids; cpuid++) { + if (cpuid_to_hartid_map(cpuid) != INVALID_HARTID) { + cpu_set_ops(cpuid); + set_cpu_possible(cpuid, true); + } + } +} +#else +#define acpi_parse_and_init_cpus(...) do { } while (0) +#endif + static void __init of_parse_and_init_cpus(void) { struct device_node *dn; @@ -118,7 +183,10 @@ static void __init of_parse_and_init_cpus(void) void __init setup_smp(void) { - of_parse_and_init_cpus(); + if (acpi_disabled) + of_parse_and_init_cpus(); + else + acpi_parse_and_init_cpus(); } static int start_secondary_cpu(int cpu, struct task_struct *tidle)