Blackfin: flush caches on SMP when one core calls another via IPI
Sometimes a SMP system will randomly panic at boot. This is due to caches being out of sync when one core tries to signal the other. So when one core calls another via IPI, flush the data caches. Signed-off-by: Yi Li <yi.li@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
This commit is contained in:
Родитель
3630ac34b0
Коммит
c9784ebb23
|
@ -122,9 +122,17 @@ static void ipi_call_function(unsigned int cpu, struct ipi_message *msg)
|
||||||
wait = msg->call_struct.wait;
|
wait = msg->call_struct.wait;
|
||||||
cpu_clear(cpu, msg->call_struct.pending);
|
cpu_clear(cpu, msg->call_struct.pending);
|
||||||
func(info);
|
func(info);
|
||||||
if (wait)
|
if (wait) {
|
||||||
|
#ifdef __ARCH_SYNC_CORE_DCACHE
|
||||||
|
/*
|
||||||
|
* 'wait' usually means synchronization between CPUs.
|
||||||
|
* Invalidate D cache in case shared data was changed
|
||||||
|
* by func() to ensure cache coherence.
|
||||||
|
*/
|
||||||
|
resync_core_dcache();
|
||||||
|
#endif
|
||||||
cpu_clear(cpu, msg->call_struct.waitmask);
|
cpu_clear(cpu, msg->call_struct.waitmask);
|
||||||
else
|
} else
|
||||||
kfree(msg);
|
kfree(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,6 +227,13 @@ int smp_call_function(void (*func)(void *info), void *info, int wait)
|
||||||
blackfin_dcache_invalidate_range(
|
blackfin_dcache_invalidate_range(
|
||||||
(unsigned long)(&msg->call_struct.waitmask),
|
(unsigned long)(&msg->call_struct.waitmask),
|
||||||
(unsigned long)(&msg->call_struct.waitmask));
|
(unsigned long)(&msg->call_struct.waitmask));
|
||||||
|
#ifdef __ARCH_SYNC_CORE_DCACHE
|
||||||
|
/*
|
||||||
|
* Invalidate D cache in case shared data was changed by
|
||||||
|
* other processors to ensure cache coherence.
|
||||||
|
*/
|
||||||
|
resync_core_dcache();
|
||||||
|
#endif
|
||||||
kfree(msg);
|
kfree(msg);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -261,6 +276,13 @@ int smp_call_function_single(int cpuid, void (*func) (void *info), void *info,
|
||||||
blackfin_dcache_invalidate_range(
|
blackfin_dcache_invalidate_range(
|
||||||
(unsigned long)(&msg->call_struct.waitmask),
|
(unsigned long)(&msg->call_struct.waitmask),
|
||||||
(unsigned long)(&msg->call_struct.waitmask));
|
(unsigned long)(&msg->call_struct.waitmask));
|
||||||
|
#ifdef __ARCH_SYNC_CORE_DCACHE
|
||||||
|
/*
|
||||||
|
* Invalidate D cache in case shared data was changed by
|
||||||
|
* other processors to ensure cache coherence.
|
||||||
|
*/
|
||||||
|
resync_core_dcache();
|
||||||
|
#endif
|
||||||
kfree(msg);
|
kfree(msg);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче