[RFC,v2,06/35] arm64: setup: Switch over to GENERIC_CPU_DEVICES using arch_register_cpu()
Message ID | 20230913163823.7880-7-james.morse@arm.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp74024vqi; Wed, 13 Sep 2023 19:59:03 -0700 (PDT) X-Google-Smtp-Source: AGHT+IH6vtCY9HqH4t42qvhLnQkl417FZo9U18t7f/JGoiGqH4/QI4YCSozEMEFn+ogpShs+BaIw X-Received: by 2002:a17:90a:9417:b0:26f:87d1:e48 with SMTP id r23-20020a17090a941700b0026f87d10e48mr862209pjo.20.1694660342909; Wed, 13 Sep 2023 19:59:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694660342; cv=none; d=google.com; s=arc-20160816; b=q9LbeQknYdtpGRQHqACVREFZsb5SULC1AirFC5cwk7zwNzQIOAN/dHXtJLQXU6VhJF 1cjLLTdZ84NJ/ojifBC3g+UD0kV6xzsS9JwfPRvexahbvIMYK+Efs5Il7bxeqq23Pfzs c+ldi1h6nWZw/sTkxWxo7L6HlKwnjw8MRUlBvtmxamVOhnI7NXgKsc55Sv0ud7WqWEjs CFMx5Of8wGsnZGUjMkbL35HkfWWsvh1/HJBir7RJ9roB+qcHLORNo54TOXdF2LiWZxyU wVW8coebpEr0xfbnr8fv9JDtE7G9RUy2hBD95/h0GglrJbMcvya2dnEQUqZyjqAVSeEa roqw== 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; bh=jDAEm+yVMTd95B0G9tQuwSGx+8rybFj95oMdwyrSpxA=; fh=2nhVWB0fZ+8YH0lLFpnF/Mo8eq+n1VMLe+b+IpvS0g0=; b=tqLFZOIpUCeumcvHfD66nyDDr1BjvmPSReM/h83jZjO3Lig/uDS0zh+//8o4gEuYkc Io5kiN4ohXnnk7D7wmGjAZfamuzvyHGErlHcCAgW4iFZ6fcZelIbV1HHB8FXJtVFtL29 hSbrndHJlWLmj5saKlmyyBMNyDrzTSRcRndfDGOLTw9rUag9haIe1Ez10CC5I+pRlzI3 tQQXQJOxs0k/bXuV/e2hExUBbpYRCDTnuhuCoafZHc+pbV4zvYLQuJBTlSpNn4wzdL2t n0qDnUkehiqvJqoJARfjeytNLaQR+VGk5x3uFy3uxDY0utmP4e8IIhM6z8GQH6zq454u 8UHQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id a21-20020a63e855000000b00563e9d3d78csi501967pgk.422.2023.09.13.19.59.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Sep 2023 19:59:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 9A69881C7AB7; Wed, 13 Sep 2023 09:39:20 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230458AbjIMQjR (ORCPT <rfc822;pwkd43@gmail.com> + 35 others); Wed, 13 Sep 2023 12:39:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41784 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230400AbjIMQjJ (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 13 Sep 2023 12:39:09 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 7A964198B; Wed, 13 Sep 2023 09:39:05 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 437381FB; Wed, 13 Sep 2023 09:39:42 -0700 (PDT) Received: from merodach.members.linode.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 47F8C3F5A1; Wed, 13 Sep 2023 09:39:03 -0700 (PDT) From: James Morse <james.morse@arm.com> To: linux-pm@vger.kernel.org, loongarch@lists.linux.dev, linux-acpi@vger.kernel.org, linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-riscv@lists.infradead.org, kvmarm@lists.linux.dev Cc: x86@kernel.org, Salil Mehta <salil.mehta@huawei.com>, Russell King <linux@armlinux.org.uk>, Jean-Philippe Brucker <jean-philippe@linaro.org>, jianyong.wu@arm.com, justin.he@arm.com Subject: [RFC PATCH v2 06/35] arm64: setup: Switch over to GENERIC_CPU_DEVICES using arch_register_cpu() Date: Wed, 13 Sep 2023 16:37:54 +0000 Message-Id: <20230913163823.7880-7-james.morse@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20230913163823.7880-1-james.morse@arm.com> References: <20230913163823.7880-1-james.morse@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Wed, 13 Sep 2023 09:39:20 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1776980164075555607 X-GMAIL-MSGID: 1776980164075555607 |
Series |
ACPI/arm64: add support for virtual cpuhotplug
|
|
Commit Message
James Morse
Sept. 13, 2023, 4:37 p.m. UTC
To allow ACPI's _STA value to hide CPUs that are present, but not
available to online right now due to VMM or firmware policy, the
register_cpu() call needs to be made by the ACPI machinery when ACPI
is in use. This allows it to hide CPUs that are unavailable from sysfs.
Switching to GENERIC_CPU_DEVICES is an intermediate step to allow all
five ACPI architectures to be modified at once.
Switch over to GENERIC_CPU_DEVICES, and provide an arch_register_cpu()
that populates the hotpluggable flag. arch_register_cpu() is also the
interface the ACPI machinery expects.
The struct cpu in struct cpuinfo_arm64 is never used directly, remove
it to use the one GENERIC_CPU_DEVICES provides.
This changes the CPUs visible in sysfs from possible to present, but
on arm64 smp_prepare_cpus() ensures these are the same.
Signed-off-by: James Morse <james.morse@arm.com>
---
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/cpu.h | 1 -
arch/arm64/kernel/setup.c | 13 ++++---------
3 files changed, 5 insertions(+), 10 deletions(-)
Comments
On Wed, Sep 13, 2023 at 04:37:54PM +0000, James Morse wrote: > To allow ACPI's _STA value to hide CPUs that are present, but not > available to online right now due to VMM or firmware policy, the > register_cpu() call needs to be made by the ACPI machinery when ACPI > is in use. This allows it to hide CPUs that are unavailable from sysfs. > > Switching to GENERIC_CPU_DEVICES is an intermediate step to allow all > five ACPI architectures to be modified at once. > > Switch over to GENERIC_CPU_DEVICES, and provide an arch_register_cpu() > that populates the hotpluggable flag. arch_register_cpu() is also the > interface the ACPI machinery expects. > > The struct cpu in struct cpuinfo_arm64 is never used directly, remove > it to use the one GENERIC_CPU_DEVICES provides. > > This changes the CPUs visible in sysfs from possible to present, but > on arm64 smp_prepare_cpus() ensures these are the same. > > Signed-off-by: James Morse <james.morse@arm.com> Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
On Wed, 13 Sep 2023 16:37:54 +0000 James Morse <james.morse@arm.com> wrote: > To allow ACPI's _STA value to hide CPUs that are present, but not > available to online right now due to VMM or firmware policy, the > register_cpu() call needs to be made by the ACPI machinery when ACPI > is in use. This allows it to hide CPUs that are unavailable from sysfs. > > Switching to GENERIC_CPU_DEVICES is an intermediate step to allow all > five ACPI architectures to be modified at once. > > Switch over to GENERIC_CPU_DEVICES, and provide an arch_register_cpu() > that populates the hotpluggable flag. arch_register_cpu() is also the > interface the ACPI machinery expects. > > The struct cpu in struct cpuinfo_arm64 is never used directly, remove > it to use the one GENERIC_CPU_DEVICES provides. > > This changes the CPUs visible in sysfs from possible to present, but > on arm64 smp_prepare_cpus() ensures these are the same. > > Signed-off-by: James Morse <james.morse@arm.com> After this the earlier question about ordering of cpu_dev_init() and node_dev_init() is relevant. Why won't node_dev_init() call get_cpu_devce() which queries per_cpu(cpu_sys_devices) and get NULL as we haven't yet filled that in? Or does it do so but that doesn't matter as well create the relevant links later? I've not had enough coffee yet today so might be missing the obvious! Jonathan > --- > arch/arm64/Kconfig | 1 + > arch/arm64/include/asm/cpu.h | 1 - > arch/arm64/kernel/setup.c | 13 ++++--------- > 3 files changed, 5 insertions(+), 10 deletions(-) > > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig > index b10515c0200b..7b3990abf87a 100644 > --- a/arch/arm64/Kconfig > +++ b/arch/arm64/Kconfig > @@ -132,6 +132,7 @@ config ARM64 > select GENERIC_ARCH_TOPOLOGY > select GENERIC_CLOCKEVENTS_BROADCAST > select GENERIC_CPU_AUTOPROBE > + select GENERIC_CPU_DEVICES > select GENERIC_CPU_VULNERABILITIES > select GENERIC_EARLY_IOREMAP > select GENERIC_IDLE_POLL_SETUP > diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h > index e749838b9c5d..887bd0d992bb 100644 > --- a/arch/arm64/include/asm/cpu.h > +++ b/arch/arm64/include/asm/cpu.h > @@ -38,7 +38,6 @@ struct cpuinfo_32bit { > }; > > struct cpuinfo_arm64 { > - struct cpu cpu; > struct kobject kobj; > u64 reg_ctr; > u64 reg_cntfrq; > diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c > index 417a8a86b2db..165bd2c0dd5a 100644 > --- a/arch/arm64/kernel/setup.c > +++ b/arch/arm64/kernel/setup.c > @@ -402,19 +402,14 @@ static inline bool cpu_can_disable(unsigned int cpu) > return false; > } > > -static int __init topology_init(void) > +int arch_register_cpu(int num) > { > - int i; > + struct cpu *cpu = &per_cpu(cpu_devices, num); > > - for_each_possible_cpu(i) { > - struct cpu *cpu = &per_cpu(cpu_data.cpu, i); > - cpu->hotpluggable = cpu_can_disable(i); > - register_cpu(cpu, i); > - } > + cpu->hotpluggable = cpu_can_disable(num); > > - return 0; > + return register_cpu(cpu, num); > } > -subsys_initcall(topology_init); > > static void dump_kernel_offset(void) > {
On Thu, Sep 14, 2023 at 12:27:15PM +0100, Jonathan Cameron wrote: > On Wed, 13 Sep 2023 16:37:54 +0000 > James Morse <james.morse@arm.com> wrote: > > > To allow ACPI's _STA value to hide CPUs that are present, but not > > available to online right now due to VMM or firmware policy, the > > register_cpu() call needs to be made by the ACPI machinery when ACPI > > is in use. This allows it to hide CPUs that are unavailable from sysfs. > > > > Switching to GENERIC_CPU_DEVICES is an intermediate step to allow all > > five ACPI architectures to be modified at once. > > > > Switch over to GENERIC_CPU_DEVICES, and provide an arch_register_cpu() > > that populates the hotpluggable flag. arch_register_cpu() is also the > > interface the ACPI machinery expects. > > > > The struct cpu in struct cpuinfo_arm64 is never used directly, remove > > it to use the one GENERIC_CPU_DEVICES provides. > > > > This changes the CPUs visible in sysfs from possible to present, but > > on arm64 smp_prepare_cpus() ensures these are the same. > > > > Signed-off-by: James Morse <james.morse@arm.com> > > After this the earlier question about ordering of cpu_dev_init() > and node_dev_init() is relevant. > > Why won't node_dev_init() call > get_cpu_devce() which queries per_cpu(cpu_sys_devices) > and get NULL as we haven't yet filled that in? > > Or does it do so but that doesn't matter as well create the > relevant links later? node_dev_init() will walk through the nodes calling register_one_node() on each. This will trickle down to __register_one_node() which walks all present CPUs, calling register_cpu_under_node() on each. register_cpu_under_node() will call get_cpu_device(cpu) for each and will return NULL until the CPU is registered using register_cpu(), which will now happen _after_ node_dev_init(). So, at this point, CPUs won't get registered, and initially one might think that's a problem. However, register_cpu() will itself call register_cpu_under_node(), where get_cpu_device() will return the now populated entry, and the sysfs links will be created. So, I think what you've spotted is a potential chunk of code that isn't necessary when using GENERIC_CPU_DEVICES after this change!
On Thu, 14 Sep 2023 15:07:22 +0100 "Russell King (Oracle)" <linux@armlinux.org.uk> wrote: > On Thu, Sep 14, 2023 at 12:27:15PM +0100, Jonathan Cameron wrote: > > On Wed, 13 Sep 2023 16:37:54 +0000 > > James Morse <james.morse@arm.com> wrote: > > > > > To allow ACPI's _STA value to hide CPUs that are present, but not > > > available to online right now due to VMM or firmware policy, the > > > register_cpu() call needs to be made by the ACPI machinery when ACPI > > > is in use. This allows it to hide CPUs that are unavailable from sysfs. > > > > > > Switching to GENERIC_CPU_DEVICES is an intermediate step to allow all > > > five ACPI architectures to be modified at once. > > > > > > Switch over to GENERIC_CPU_DEVICES, and provide an arch_register_cpu() > > > that populates the hotpluggable flag. arch_register_cpu() is also the > > > interface the ACPI machinery expects. > > > > > > The struct cpu in struct cpuinfo_arm64 is never used directly, remove > > > it to use the one GENERIC_CPU_DEVICES provides. > > > > > > This changes the CPUs visible in sysfs from possible to present, but > > > on arm64 smp_prepare_cpus() ensures these are the same. > > > > > > Signed-off-by: James Morse <james.morse@arm.com> > > > > After this the earlier question about ordering of cpu_dev_init() > > and node_dev_init() is relevant. > > > > Why won't node_dev_init() call > > get_cpu_devce() which queries per_cpu(cpu_sys_devices) > > and get NULL as we haven't yet filled that in? > > > > Or does it do so but that doesn't matter as well create the > > relevant links later? > > node_dev_init() will walk through the nodes calling register_one_node() > on each. This will trickle down to __register_one_node() which walks > all present CPUs, calling register_cpu_under_node() on each. > > register_cpu_under_node() will call get_cpu_device(cpu) for each and > will return NULL until the CPU is registered using register_cpu(), > which will now happen _after_ node_dev_init(). > > So, at this point, CPUs won't get registered, and initially one might > think that's a problem. > > However, register_cpu() will itself call register_cpu_under_node(), > where get_cpu_device() will return the now populated entry, and the > sysfs links will be created. > > So, I think what you've spotted is a potential chunk of code that > isn't necessary when using GENERIC_CPU_DEVICES after this change! > Makes sense thanks. I was just being too lazy to check and bouncing it back at James! *looks guilty* Jonathan
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index b10515c0200b..7b3990abf87a 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -132,6 +132,7 @@ config ARM64 select GENERIC_ARCH_TOPOLOGY select GENERIC_CLOCKEVENTS_BROADCAST select GENERIC_CPU_AUTOPROBE + select GENERIC_CPU_DEVICES select GENERIC_CPU_VULNERABILITIES select GENERIC_EARLY_IOREMAP select GENERIC_IDLE_POLL_SETUP diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h index e749838b9c5d..887bd0d992bb 100644 --- a/arch/arm64/include/asm/cpu.h +++ b/arch/arm64/include/asm/cpu.h @@ -38,7 +38,6 @@ struct cpuinfo_32bit { }; struct cpuinfo_arm64 { - struct cpu cpu; struct kobject kobj; u64 reg_ctr; u64 reg_cntfrq; diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 417a8a86b2db..165bd2c0dd5a 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -402,19 +402,14 @@ static inline bool cpu_can_disable(unsigned int cpu) return false; } -static int __init topology_init(void) +int arch_register_cpu(int num) { - int i; + struct cpu *cpu = &per_cpu(cpu_devices, num); - for_each_possible_cpu(i) { - struct cpu *cpu = &per_cpu(cpu_data.cpu, i); - cpu->hotpluggable = cpu_can_disable(i); - register_cpu(cpu, i); - } + cpu->hotpluggable = cpu_can_disable(num); - return 0; + return register_cpu(cpu, num); } -subsys_initcall(topology_init); static void dump_kernel_offset(void) {