From: Mark Rutland <mark.rutland@arm.com>
To: David Woodhouse <dwmw2@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
x86@kernel.org, "H . Peter Anvin" <hpa@zytor.com>,
Paolo Bonzini <pbonzini@redhat.com>,
"Paul E . McKenney" <paulmck@kernel.org>,
linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
rcu@vger.kernel.org, mimoja@mimoja.de, hewenliang4@huawei.com,
hushiyuan@huawei.com, luolongjun@huawei.com,
hejingxian@huawei.com
Subject: Re: [PATCH v2 3/7] cpu/hotplug: Add dynamic parallel bringup states before CPUHP_BRINGUP_CPU
Date: Tue, 14 Dec 2021 14:24:22 +0000 [thread overview]
Message-ID: <YbipFmlKSf1UuisZ@FVFF77S0Q05N> (raw)
In-Reply-To: <20211214123250.88230-4-dwmw2@infradead.org>
On Tue, Dec 14, 2021 at 12:32:46PM +0000, David Woodhouse wrote:
> From: David Woodhouse <dwmw@amazon.co.uk>
>
> If the platform registers these states, bring all CPUs to each registered
> state in turn, before the final bringup to CPUHP_BRINGUP_CPU. This allows
> the architecture to parallelise the slow asynchronous tasks like sending
> INIT/SIPI and waiting for the AP to come to life.
>
> There is a subtlety here: even with an empty CPUHP_BP_PARALLEL_DYN step,
> this means that *all* CPUs are brought through the prepare states and to
> CPUHP_BP_PREPARE_DYN before any of them are taken to CPUHP_BRINGUP_CPU
> and then are allowed to run for themselves to CPUHP_ONLINE.
>
> So any combination of prepare/start calls which depend on A-B ordering
> for each CPU in turn, such as the X2APIC code which used to allocate a
> cluster mask 'just in case' and store it in a global variable in the
> prep stage, then potentially consume that preallocated structure from
> the AP and set the global pointer to NULL to be reallocated in
> CPUHP_X2APIC_PREPARE for the next CPU... would explode horribly.
>
> We believe that X2APIC was the only such case, for x86. But this is why
> it remains an architecture opt-in. For now.
It might be worth elaborating with a non-x86 example, e.g.
| We believe that X2APIC was the only such case, for x86. Other architectures
| have similar requirements with global variables used during bringup (e.g.
| `secondary_data` on arm/arm64), so architectures must opt-in for now.
... so that we have a specific example of how unconditionally enabling this for
all architectures would definitely break things today.
FWIW, that's something I would like to cleanup for arm64 for general
robustness, and if that would make it possible for us to have parallel bringup
in future that would be a nice bonus.
> Note that the new parallel stages do *not* yet bring each AP to the
> CPUHP_BRINGUP_CPU state. The final loop in bringup_nonboot_cpus() is
> untouched, bringing each AP in turn from the final PARALLEL_DYN state
> (or all the way from CPUHP_OFFLINE) to CPUHP_BRINGUP_CPU and then
> waiting for that AP to do its own processing and reach CPUHP_ONLINE
> before releasing the next. Parallelising that part by bringing them all
> to CPUHP_BRINGUP_CPU and then waiting for them all is an exercise for
> the future.
>
> Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
> ---
> include/linux/cpuhotplug.h | 2 ++
> kernel/cpu.c | 27 +++++++++++++++++++++++++--
> 2 files changed, 27 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
> index 773c83730906..45c327538321 100644
> --- a/include/linux/cpuhotplug.h
> +++ b/include/linux/cpuhotplug.h
> @@ -131,6 +131,8 @@ enum cpuhp_state {
> CPUHP_MIPS_SOC_PREPARE,
> CPUHP_BP_PREPARE_DYN,
> CPUHP_BP_PREPARE_DYN_END = CPUHP_BP_PREPARE_DYN + 20,
> + CPUHP_BP_PARALLEL_DYN,
> + CPUHP_BP_PARALLEL_DYN_END = CPUHP_BP_PARALLEL_DYN + 4,
> CPUHP_BRINGUP_CPU,
>
> /*
> diff --git a/kernel/cpu.c b/kernel/cpu.c
> index 192e43a87407..1a46eb57d8f7 100644
> --- a/kernel/cpu.c
> +++ b/kernel/cpu.c
> @@ -1462,6 +1462,24 @@ int bringup_hibernate_cpu(unsigned int sleep_cpu)
> void bringup_nonboot_cpus(unsigned int setup_max_cpus)
> {
> unsigned int cpu;
> + int n = setup_max_cpus - num_online_cpus();
> +
> + /* ∀ parallel pre-bringup state, bring N CPUs to it */
I see you have a fancy maths keyboard. ;)
It might be worth using a few more words here for clarity, e.g.
/*
* Bring all nonboot CPUs through each pre-bringup state in turn
*/
Thanks,
Mark.
> + if (n > 0) {
> + enum cpuhp_state st = CPUHP_BP_PARALLEL_DYN;
> +
> + while (st <= CPUHP_BP_PARALLEL_DYN_END &&
> + cpuhp_hp_states[st].name) {
> + int i = n;
> +
> + for_each_present_cpu(cpu) {
> + cpu_up(cpu, st);
> + if (!--i)
> + break;
> + }
> + st++;
> + }
> + }
>
> for_each_present_cpu(cpu) {
> if (num_online_cpus() >= setup_max_cpus)
> @@ -1829,6 +1847,10 @@ static int cpuhp_reserve_state(enum cpuhp_state state)
> step = cpuhp_hp_states + CPUHP_BP_PREPARE_DYN;
> end = CPUHP_BP_PREPARE_DYN_END;
> break;
> + case CPUHP_BP_PARALLEL_DYN:
> + step = cpuhp_hp_states + CPUHP_BP_PARALLEL_DYN;
> + end = CPUHP_BP_PARALLEL_DYN_END;
> + break;
> default:
> return -EINVAL;
> }
> @@ -1853,14 +1875,15 @@ static int cpuhp_store_callbacks(enum cpuhp_state state, const char *name,
> /*
> * If name is NULL, then the state gets removed.
> *
> - * CPUHP_AP_ONLINE_DYN and CPUHP_BP_PREPARE_DYN are handed out on
> + * CPUHP_AP_ONLINE_DYN and CPUHP_BP_P*_DYN are handed out on
> * the first allocation from these dynamic ranges, so the removal
> * would trigger a new allocation and clear the wrong (already
> * empty) state, leaving the callbacks of the to be cleared state
> * dangling, which causes wreckage on the next hotplug operation.
> */
> if (name && (state == CPUHP_AP_ONLINE_DYN ||
> - state == CPUHP_BP_PREPARE_DYN)) {
> + state == CPUHP_BP_PREPARE_DYN ||
> + state == CPUHP_BP_PARALLEL_DYN)) {
> ret = cpuhp_reserve_state(state);
> if (ret < 0)
> return ret;
> --
> 2.31.1
>
next prev parent reply other threads:[~2021-12-14 14:24 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-14 12:32 [PATCH v2 0/7] Parallel CPU bringup for x86_64 David Woodhouse
2021-12-14 12:32 ` [PATCH v2 1/7] x86/apic/x2apic: Fix parallel handling of cluster_mask David Woodhouse
2021-12-14 17:10 ` Sean Christopherson
2021-12-14 21:27 ` David Woodhouse
2021-12-14 12:32 ` [PATCH v2 2/7] cpu/hotplug: Move idle_thread_get() to <linux/smpboot.h> David Woodhouse
2021-12-14 12:32 ` [PATCH v2 3/7] cpu/hotplug: Add dynamic parallel bringup states before CPUHP_BRINGUP_CPU David Woodhouse
2021-12-14 14:24 ` Mark Rutland [this message]
2021-12-14 20:32 ` David Woodhouse
2021-12-15 11:10 ` Mark Rutland
2021-12-15 15:16 ` David Woodhouse
2021-12-14 12:32 ` [PATCH v2 4/7] x86/smpboot: Reference count on smpboot_setup_warm_reset_vector() David Woodhouse
2021-12-14 12:32 ` [PATCH v2 5/7] x86/smpboot: Split up native_cpu_up into separate phases and document them David Woodhouse
2021-12-14 12:32 ` [PATCH v2 6/7] x86/smpboot: Support parallel startup of secondary CPUs David Woodhouse
2021-12-14 12:32 ` [PATCH v2 7/7] x86/smpboot: Send INIT/SIPI/SIPI to secondary CPUs in parallel David Woodhouse
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YbipFmlKSf1UuisZ@FVFF77S0Q05N \
--to=mark.rutland@arm.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=dwmw2@infradead.org \
--cc=hejingxian@huawei.com \
--cc=hewenliang4@huawei.com \
--cc=hpa@zytor.com \
--cc=hushiyuan@huawei.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luolongjun@huawei.com \
--cc=mimoja@mimoja.de \
--cc=mingo@redhat.com \
--cc=paulmck@kernel.org \
--cc=pbonzini@redhat.com \
--cc=rcu@vger.kernel.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.