[patch V4 24/30] x86/microcode: Replace the all in one rendevouz handler
From: Thomas Gleixner
Date: Mon Oct 02 2023 - 08:00:58 EST
From: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
with a new handler which just separates the control flow of primary and
secondary CPUs.
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
---
arch/x86/kernel/cpu/microcode/core.c | 51 ++++++-----------------------------
1 file changed, 9 insertions(+), 42 deletions(-)
---
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -297,7 +297,7 @@ struct microcode_ctrl {
};
static DEFINE_PER_CPU(struct microcode_ctrl, ucode_ctrl);
-static atomic_t late_cpus_in, late_cpus_out;
+static atomic_t late_cpus_in;
static bool wait_for_cpus(atomic_t *cnt)
{
@@ -333,7 +333,7 @@ static bool wait_for_ctrl(void)
return false;
}
-static __maybe_unused void load_secondary(unsigned int cpu)
+static void load_secondary(unsigned int cpu)
{
unsigned int ctrl_cpu = this_cpu_read(ucode_ctrl.ctrl_cpu);
enum ucode_state ret;
@@ -368,7 +368,7 @@ static __maybe_unused void load_secondar
this_cpu_write(ucode_ctrl.ctrl, SCTRL_DONE);
}
-static __maybe_unused void load_primary(unsigned int cpu)
+static void load_primary(unsigned int cpu)
{
struct cpumask *secondaries = topology_sibling_cpumask(cpu);
enum sibling_ctrl ctrl;
@@ -405,46 +405,14 @@ static __maybe_unused void load_primary(
static int load_cpus_stopped(void *unused)
{
- int cpu = smp_processor_id();
- enum ucode_state ret;
-
- /*
- * Wait for all CPUs to arrive. A load will not be attempted unless all
- * CPUs show up.
- * */
- if (!wait_for_cpus(&late_cpus_in)) {
- this_cpu_write(ucode_ctrl.result, UCODE_TIMEOUT);
- return 0;
- }
-
- /*
- * On an SMT system, it suffices to load the microcode on one sibling of
- * the core because the microcode engine is shared between the threads.
- * Synchronization still needs to take place so that no concurrent
- * loading attempts happen on multiple threads of an SMT core. See
- * below.
- */
- if (cpumask_first(topology_sibling_cpumask(cpu)) != cpu)
- goto wait_for_siblings;
+ unsigned int cpu = smp_processor_id();
- ret = microcode_ops->apply_microcode(cpu);
- this_cpu_write(ucode_ctrl.result, ret);
-
-wait_for_siblings:
- if (!wait_for_cpus(&late_cpus_out))
- panic("Timeout during microcode update!\n");
-
- /*
- * At least one thread has completed update on each core.
- * For others, simply call the update to make sure the
- * per-cpu cpuinfo can be updated with right microcode
- * revision.
- */
- if (cpumask_first(topology_sibling_cpumask(cpu)) == cpu)
- return 0;
+ if (this_cpu_read(ucode_ctrl.ctrl_cpu) == cpu)
+ load_primary(cpu);
+ else
+ load_secondary(cpu);
- ret = microcode_ops->apply_microcode(cpu);
- this_cpu_write(ucode_ctrl.result, ret);
+ /* No point to wait here. The CPUs will all wait in stop_machine(). */
return 0;
}
@@ -458,7 +426,6 @@ static int load_late_stop_cpus(void)
pr_err("You should switch to early loading, if possible.\n");
atomic_set(&late_cpus_in, num_online_cpus());
- atomic_set(&late_cpus_out, num_online_cpus());
/*
* Take a snapshot before the microcode update in order to compare and