From: "Chang S. Bae" <chang.seok.bae@intel.com>
To: Borislav Petkov <bp@alien8.de>, "Kaplan, David" <David.Kaplan@amd.com>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"x86@kernel.org" <x86@kernel.org>,
"tglx@linutronix.de" <tglx@linutronix.de>,
"mingo@redhat.com" <mingo@redhat.com>,
"dave.hansen@linux.intel.com" <dave.hansen@linux.intel.com>,
"peterz@infradead.org" <peterz@infradead.org>
Subject: Re: [PATCH 1/7] stop_machine: Introduce stop_machine_nmi()
Date: Thu, 5 Feb 2026 18:14:39 -0800 [thread overview]
Message-ID: <80c16fe8-471a-4e31-987c-15d377f8f165@intel.com> (raw)
In-Reply-To: <20260202105411.GVaYCCUygtEUNrMUtG@fat_crate.local>
On 2/2/2026 2:54 AM, Borislav Petkov wrote:
...
> @@ -174,8 +174,26 @@ struct multi_stop_data {
>
> enum multi_stop_state state;
> atomic_t thread_ack;
> +
> + bool use_nmi;
> +
> + /*
> + * cpumasks of CPUs on which to raise an NMI; used in the NMI
> + * stomp_machine variant. nmi_cpus_done is used for tracking
> + * when the NMI handler has executed successfully.
> + */
> + struct cpumask nmi_cpus;
> + struct cpumask nmi_cpus_done;
> +
> +};
Looks like every stop_machine variant then will spend stack for these
masks. It seems they could be cpumask_var_t.
Alternatively, to make it simple further, a per-CPU variable could
achieve this if I understand correctly:
struct stop_machine_nmi_ctrl {
...
bool done;
}
Then,
for_each_cpu(cpu, cpus)
per_cpu(stop_machine_nmi_ctrl.done, cpu) = false;
...
ret = stop_cpus(cpu_online_mask, multi_cpu_stop, &msdata);
...
for_each_cpu(cpu, cpus) {
if (!per_cpu(stop_machine_nmi_ctrl.done, cpu)) {
pr_err("Some CPUs didn't run ...\n");
return -EINVAL;
}
}
Or, I guess even the msdata pointer alone could do that too -- setting
it before and checking if NULL after.
> +static int __stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data,
> + const struct cpumask *cpus, bool use_nmi)
> {
> struct multi_stop_data msdata = {
> .fn = fn,
> .data = data,
> .num_threads = num_online_cpus(),
> .active_cpus = cpus,
> + .use_nmi = use_nmi,
> };
> + int ret, cpu;
> +
> + if (use_nmi) {
> + cpumask_copy(&msdata.nmi_cpus, cpus);
> + cpumask_clear(&msdata.nmi_cpus_done);
> + }
>
> lockdep_assert_cpus_held();
>
> @@ -617,7 +677,32 @@ int stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data,
>
> /* Set the initial state and stop all online cpus. */
> set_state(&msdata, MULTI_STOP_PREPARE);
> - return stop_cpus(cpu_online_mask, multi_cpu_stop, &msdata);
> + ret = stop_cpus(cpu_online_mask, multi_cpu_stop, &msdata);
> +
> + if (!use_nmi)
> + return ret;
> +
> + if (!cpumask_equal(cpus, &msdata.nmi_cpus_done)) {
> + pr_err("Some CPUs didn't run the stomp_machine NMI handler\n");
> + return -EINVAL;
> + } else {
> + for_each_cpu(cpu, cpus)
> + ret |= per_cpu(stop_machine_nmi_ctrl.err, cpu);
This error accumulation here makes sense to me though,
Currently, stop_machine() documents:
/*
...
* Return: 0 if all invocations of @fn return zero. Otherwise, the
* value returned by an arbitrarily chosen member of the set of calls to
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* @fn that returned non-zero.
*/
This behavior dates back to:
commit 1142d810298e694 ("cpu_stop: implement stop_cpu[s]()")
where cpu_stopper_thread() does:
struct cpu_stop_done *done = work->done;
...
ret = fn(arg);
if (ret)
done->ret = ret;
So the return value is overwritten instead of accumulation, while struct
cpu_stop_done is shared like the note:
/*
* Structure to determine completion condition and record errors. May
* be shared by works on different cpus.
*/
I don't know whether that was an intentional design choice or not. But,
at least the NMI variant might have a slight different semantic in this
regard.
next prev parent reply other threads:[~2026-02-06 2:14 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-25 1:42 [PATCH 0/7] x86/microcode: Refactor NMI-based rendezvous mechanism to stop-machine Chang S. Bae
2026-01-25 1:42 ` [PATCH 1/7] stop_machine: Introduce stop_machine_nmi() Chang S. Bae
2026-01-26 11:51 ` kernel test robot
2026-01-27 14:49 ` Borislav Petkov
2026-01-27 19:15 ` Chang S. Bae
2026-01-27 15:49 ` Borislav Petkov
2026-01-27 16:00 ` Kaplan, David
2026-01-27 20:49 ` Borislav Petkov
2026-01-28 1:31 ` Kaplan, David
2026-01-28 16:35 ` Borislav Petkov
2026-01-29 12:17 ` Borislav Petkov
2026-01-29 15:47 ` Chang S. Bae
2026-02-02 10:54 ` Borislav Petkov
2026-02-06 2:14 ` Chang S. Bae [this message]
2026-03-04 16:33 ` Borislav Petkov
2026-01-28 8:02 ` Thomas Gleixner
2026-01-29 17:07 ` Chang S. Bae
2026-01-30 10:02 ` Thomas Gleixner
2026-01-25 1:42 ` [PATCH 2/7] x86/apic: Implement self-NMI support Chang S. Bae
2026-01-28 8:05 ` Thomas Gleixner
2026-01-29 16:32 ` Chang S. Bae
2026-01-25 1:42 ` [PATCH 3/7] x86/nmi: Support stop_machine_nmi() handler Chang S. Bae
2026-01-25 1:42 ` [PATCH 4/7] x86/microcode: Distinguish NMI control path on stop-machine callback Chang S. Bae
2026-01-28 8:11 ` Thomas Gleixner
2026-01-29 16:32 ` Chang S. Bae
2026-01-25 1:42 ` [PATCH 5/7] x86/microcode: Use stop-machine NMI facility Chang S. Bae
2026-01-25 1:42 ` [PATCH 6/7] x86/nmi: Reference stop-machine static key for offline microcode handler Chang S. Bae
2026-01-25 1:42 ` [PATCH 7/7] x86/microcode: Remove microcode_nmi_handler_enable Chang S. Bae
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=80c16fe8-471a-4e31-987c-15d377f8f165@intel.com \
--to=chang.seok.bae@intel.com \
--cc=David.Kaplan@amd.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®