aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorAshok Raj <ashok.raj@intel.com>2024-01-25 00:22:53 -0800
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>2024-01-31 11:57:29 +0200
commitea15f34d5fb77a0db0dd9f983b647fe5b613cf73 (patch)
tree3f8d8bd7d1bff686ad96a66fdc63e91fd2bf5672 /drivers/platform
parente272d1e1188e55259dd0e3ba2f8f744a531fdd59 (diff)
downloadlinux-ea15f34d5fb77a0db0dd9f983b647fe5b613cf73.tar.gz
platform/x86/intel/ifs: Replace the exit rendezvous with an entry rendezvous for ARRAY_BIST
ARRAY_BIST requires the test to be invoked only from one of the HT siblings of a core. If the other sibling was in mwait(), that didn't permit the test to complete and resulted in several retries before the test could finish. The exit rendezvous was introduced to keep the HT sibling busy until the primary CPU completed the test to avoid those retries. What is actually needed is to ensure that both the threads rendezvous *before* the wrmsr to trigger the test to give good chance to complete the test. The `stop_machine()` function returns only after all the CPUs complete running the function, and provides an exit rendezvous implicitly. In kernel/stop_machine.c::multi_cpu_stop(), every CPU in the mask needs to complete reaching MULTI_STOP_RUN. When all CPUs complete, the state machine moves to next state, i.e MULTI_STOP_EXIT. Thus the underlying API stop_core_cpuslocked() already provides an exit rendezvous. Add the rendezvous earlier in order to ensure the wrmsr is triggered after all CPUs reach the do_array_test(). Remove the exit rendezvous since stop_core_cpuslocked() already guarantees that. Signed-off-by: Ashok Raj <ashok.raj@intel.com> Reviewed-by: Tony Luck <tony.luck@intel.com> Link: https://lore.kernel.org/r/20240125082254.424859-5-ashok.raj@intel.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/intel/ifs/runtest.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x86/intel/ifs/runtest.c
index 21dc0046fd9b2..e3307dd8e3c4c 100644
--- a/drivers/platform/x86/intel/ifs/runtest.c
+++ b/drivers/platform/x86/intel/ifs/runtest.c
@@ -271,7 +271,7 @@ static void ifs_test_core(int cpu, struct device *dev)
}
#define SPINUNIT 100 /* 100 nsec */
-static atomic_t array_cpus_out;
+static atomic_t array_cpus_in;
/*
* Simplified cpu sibling rendezvous loop based on microcode loader __wait_for_cpus()
@@ -298,6 +298,8 @@ static int do_array_test(void *data)
int cpu = smp_processor_id();
int first;
+ wait_for_sibling_cpu(&array_cpus_in, NSEC_PER_SEC);
+
/*
* Only one logical CPU on a core needs to trigger the Array test via MSR write.
*/
@@ -309,9 +311,6 @@ static int do_array_test(void *data)
rdmsrl(MSR_ARRAY_BIST, command->data);
}
- /* Tests complete faster if the sibling is spinning here */
- wait_for_sibling_cpu(&array_cpus_out, NSEC_PER_SEC);
-
return 0;
}
@@ -332,7 +331,7 @@ static void ifs_array_test_core(int cpu, struct device *dev)
timed_out = true;
break;
}
- atomic_set(&array_cpus_out, 0);
+ atomic_set(&array_cpus_in, 0);
stop_core_cpuslocked(cpu, do_array_test, &command);
if (command.ctrl_result)