Fix possible though unlikely SMP issue reported by Robert Szeleney. One must

not use a single static variable to synchronize CPUs at two points. In an
environment where CPUs do not really run concurently (in emulation or with
logical processors) it would be possible for CPUs to get trapped in the first
synchronization while another CPU might just do its thing and change the
sync variable again. These CPUs would then never leave the first loop as the
exit condition has already passed again. The key is to use two different sync
variables like it is done in early kernel initialization. As I didn't manage
to trigger this code though I am not sure if this is gonna work.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23926 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2008-02-07 23:19:28 +00:00
parent 2836442b70
commit cfc9593fa8
+10 -14
View File
@@ -66,7 +66,8 @@ extern void reboot(void);
void (*gX86SwapFPUFunc)(void *oldState, const void *newState);
bool gHasSSE = false;
static vint32 sWaitAllCPUs;
static uint32 sCpuRendezvous;
static uint32 sCpuRendezvous2;
segment_descriptor *gGDT = NULL;
@@ -114,9 +115,7 @@ set_mtrr(void *_parameter, int cpu)
struct set_mtrr_parameter *parameter = (struct set_mtrr_parameter *)_parameter;
// wait until all CPUs have arrived here
atomic_add(&sWaitAllCPUs, 1);
while (sWaitAllCPUs != smp_get_num_cpus())
asm volatile ("pause;");
smp_cpu_rendezvous(&sCpuRendezvous, cpu);
disable_caches();
@@ -126,9 +125,7 @@ set_mtrr(void *_parameter, int cpu)
enable_caches();
// wait until all CPUs have arrived here
atomic_add(&sWaitAllCPUs, -1);
while (sWaitAllCPUs != 0)
asm volatile ("pause;");
smp_cpu_rendezvous(&sCpuRendezvous2, cpu);
}
@@ -136,9 +133,7 @@ static void
init_mtrrs(void *_unused, int cpu)
{
// wait until all CPUs have arrived here
atomic_add(&sWaitAllCPUs, 1);
while (sWaitAllCPUs != smp_get_num_cpus())
asm volatile ("pause;");
smp_cpu_rendezvous(&sCpuRendezvous, cpu);
disable_caches();
@@ -147,9 +142,7 @@ init_mtrrs(void *_unused, int cpu)
enable_caches();
// wait until all CPUs have arrived here
atomic_add(&sWaitAllCPUs, -1);
while (sWaitAllCPUs != 0)
asm volatile ("pause;");
smp_cpu_rendezvous(&sCpuRendezvous2, cpu);
}
@@ -174,6 +167,7 @@ x86_set_mtrr(uint32 index, uint64 base, uint64 length, uint8 type)
parameter.length = length;
parameter.type = type;
sCpuRendezvous = sCpuRendezvous2 = 0;
call_all_cpus(&set_mtrr, &parameter);
}
@@ -549,8 +543,10 @@ arch_cpu_init_post_modules(kernel_args *args)
close_module_list(cookie);
// initialize MTRRs if available
if (x86_count_mtrrs() > 0)
if (x86_count_mtrrs() > 0) {
sCpuRendezvous = sCpuRendezvous2 = 0;
call_all_cpus(&init_mtrrs, NULL);
}
// get optimized functions from the CPU module
if (sCpuModule != NULL && sCpuModule->get_optimized_functions != NULL) {