[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <YbjQCf29BH7aTblP@google.com>
Date: Tue, 14 Dec 2021 17:10:33 +0000
From: Sean Christopherson <seanjc@...gle.com>
To: David Woodhouse <dwmw2@...radead.org>
Cc: Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
Dave Hansen <dave.hansen@...ux.intel.com>, x86@...nel.org,
"H . Peter Anvin" <hpa@...or.com>,
Paolo Bonzini <pbonzini@...hat.com>,
"Paul E . McKenney" <paulmck@...nel.org>,
linux-kernel@...r.kernel.org, kvm@...r.kernel.org,
rcu@...r.kernel.org, mimoja@...oja.de, hewenliang4@...wei.com,
hushiyuan@...wei.com, luolongjun@...wei.com, hejingxian@...wei.com
Subject: Re: [PATCH v2 1/7] x86/apic/x2apic: Fix parallel handling of
cluster_mask
On Tue, Dec 14, 2021, David Woodhouse wrote:
> -static int alloc_clustermask(unsigned int cpu, int node)
> +static int alloc_clustermask(unsigned int cpu, u32 cluster, int node)
> {
> + struct cluster_mask *cmsk = NULL;
> + unsigned int cpu_i;
> + u32 apicid;
> +
> if (per_cpu(cluster_masks, cpu))
> return 0;
> - /*
> - * If a hotplug spare mask exists, check whether it's on the right
> - * node. If not, free it and allocate a new one.
> +
> + /* For the hotplug case, don't always allocate a new one */
> + for_each_present_cpu(cpu_i) {
> + apicid = apic->cpu_present_to_apicid(cpu_i);
> + if (apicid != BAD_APICID && apicid >> 4 == cluster) {
> + cmsk = per_cpu(cluster_masks, cpu_i);
> + if (cmsk)
> + break;
> + }
> + }
> + if (!cmsk) {
> + cmsk = kzalloc_node(sizeof(*cmsk), GFP_KERNEL, node);
> + }
> + if (!cmsk)
> + return -ENOMEM;
This can be,
if (!cmsk) {
cmsk = kzalloc_node(sizeof(*cmsk), GFP_KERNEL, node);
if (!cmsk)
return -ENOMEM;
}
which IMO is more intuitive, and it also "fixes" the unnecessary braces in thew
initial check.
> +
> + cmsk->node = node;
> + cmsk->clusterid = cluster;
> +
> + per_cpu(cluster_masks, cpu) = cmsk;
> +
> + /*
> + * As an optimisation during boot, set the cluster_mask for *all*
> + * present CPUs at once, to prevent *each* of them having to iterate
> + * over the others to find the existing cluster_mask.
> */
> - if (cluster_hotplug_mask) {
> - if (cluster_hotplug_mask->node == node)
> - return 0;
> - kfree(cluster_hotplug_mask);
> + if (system_state < SYSTEM_RUNNING) {
This can be
if (system_state >= SYSTEM_RUNNING)
return 0;
to reduce indentation below.
> + for_each_present_cpu(cpu) {
Reusing @cpu here is all kinds of confusing.
> + u32 apicid = apic->cpu_present_to_apicid(cpu);
This shadows apicid. That's completely unnecessary.
> + if (apicid != BAD_APICID && apicid >> 4 == cluster) {
A helper for retrieving the cluster from a cpu would dedup at least three instances
of this pattern.
> + struct cluster_mask **cpu_cmsk = &per_cpu(cluster_masks, cpu);
> + if (*cpu_cmsk)
> + BUG_ON(*cpu_cmsk != cmsk);
> + else
> + *cpu_cmsk = cmsk;
The if statement is a little confusing because of the double pointer. BUG_ON()
won't return, maybe write it like so?
BUG_ON(*cpu_mask && *cpu_mask != cmsk);
*cpu_cmsk = cmsk;
> + }
> + }
> }
>
> - cluster_hotplug_mask = kzalloc_node(sizeof(*cluster_hotplug_mask),
> - GFP_KERNEL, node);
> - if (!cluster_hotplug_mask)
> - return -ENOMEM;
> - cluster_hotplug_mask->node = node;
> return 0;
> }
>
> static int x2apic_prepare_cpu(unsigned int cpu)
> {
> - if (alloc_clustermask(cpu, cpu_to_node(cpu)) < 0)
> + u32 phys_apicid = apic->cpu_present_to_apicid(cpu);
> + u32 cluster = phys_apicid >> 4;
> + u32 logical_apicid = (cluster << 16) | (1 << (phys_apicid & 0xf));
> +
> + x86_cpu_to_logical_apicid[cpu] = logical_apicid;
> +
> + if (alloc_clustermask(cpu, cluster, cpu_to_node(cpu)) < 0)
> return -ENOMEM;
> if (!zalloc_cpumask_var(&per_cpu(ipi_mask, cpu), GFP_KERNEL))
> return -ENOMEM;
> --
> 2.31.1
>
Powered by blists - more mailing lists