MCS, SMP: Add clock synchronisation test
Because ksCurTime is compared cross-node now, time across nodes must be the same. Check this once during boot. Replace __atomic_signal_fence with the more correct __atomic_thread_fence, as ksNumCPUs will be changed cross-node. Signed-off-by: Indan Zupancic <Indan.Zupancic@mep-info.com>
This commit is contained in:
parent
04c096128b
commit
2a8c9683f3
5 changed files with 51 additions and 5 deletions
|
|
@ -135,3 +135,14 @@ static inline BOOT_CODE pptr_t it_alloc_paging(void)
|
|||
|
||||
/* return the amount of paging structures required to cover v_reg */
|
||||
word_t arch_get_n_paging(v_region_t it_veg);
|
||||
|
||||
#if defined(CONFIG_DEBUG_BUILD) && defined(ENABLE_SMP_SUPPORT) && defined(CONFIG_KERNEL_MCS)
|
||||
/* Test whether clocks are synchronised across nodes */
|
||||
#define ENABLE_SMP_CLOCK_SYNC_TEST_ON_BOOT
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SMP_CLOCK_SYNC_TEST_ON_BOOT
|
||||
BOOT_CODE void clock_sync_test(void);
|
||||
#else
|
||||
#define clock_sync_test()
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -274,6 +274,7 @@ BOOT_CODE static bool_t try_init_kernel_secondary_core(void)
|
|||
#endif /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
NODE_LOCK_SYS;
|
||||
|
||||
clock_sync_test();
|
||||
ksNumCPUs++;
|
||||
|
||||
init_core_state(SchedulerAction_ResumeCurrentThread);
|
||||
|
|
@ -303,8 +304,11 @@ BOOT_CODE static void release_secondary_cpus(void)
|
|||
|
||||
/* Wait until all the secondary cores are done initialising */
|
||||
while (ksNumCPUs != CONFIG_MAX_NUM_NODES) {
|
||||
/* perform a memory release+acquire to get new values of ksNumCPUs */
|
||||
__atomic_signal_fence(__ATOMIC_ACQ_REL);
|
||||
#ifdef ENABLE_SMP_CLOCK_SYNC_TEST_ON_BOOT
|
||||
NODE_STATE(ksCurTime) = getCurrentTime();
|
||||
#endif
|
||||
/* perform a memory acquire to get new values of ksNumCPUs, release for ksCurTime */
|
||||
__atomic_thread_fence(__ATOMIC_ACQ_REL);
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_SMP_SUPPORT */
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@ BOOT_CODE static bool_t try_init_kernel_secondary_core(word_t hart_id, word_t co
|
|||
init_cpu();
|
||||
NODE_LOCK_SYS;
|
||||
|
||||
clock_sync_test();
|
||||
ksNumCPUs++;
|
||||
init_core_state(SchedulerAction_ResumeCurrentThread);
|
||||
ifence_local();
|
||||
|
|
@ -171,11 +172,14 @@ BOOT_CODE static void release_secondary_cores(void)
|
|||
fence_w_r();
|
||||
|
||||
while (ksNumCPUs != CONFIG_MAX_NUM_NODES) {
|
||||
__atomic_signal_fence(__ATOMIC_ACQ_REL);
|
||||
#ifdef ENABLE_SMP_CLOCK_SYNC_TEST_ON_BOOT
|
||||
NODE_STATE(ksCurTime) = getCurrentTime();
|
||||
#endif
|
||||
__atomic_thread_fence(__ATOMIC_ACQ_REL);
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_SMP_SUPPORT */
|
||||
|
||||
#endif
|
||||
/* Main kernel initialisation function. */
|
||||
|
||||
static BOOT_CODE bool_t try_init_kernel(
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <config.h>
|
||||
#include <arch/machine.h>
|
||||
#include <arch/machine/timer.h>
|
||||
#include <arch/kernel/boot_sys.h>
|
||||
#include <arch/kernel/smp_sys.h>
|
||||
#include <smp/lock.h>
|
||||
|
|
@ -64,7 +65,12 @@ BOOT_CODE void start_boot_aps(void)
|
|||
start_cpu(boot_state.cpus[current_ap_index], BOOT_NODE_PADDR);
|
||||
|
||||
/* wait for current AP to boot up */
|
||||
while (smp_aps_index == current_ap_index);
|
||||
while (smp_aps_index == current_ap_index) {
|
||||
#ifdef ENABLE_SMP_CLOCK_SYNC_TEST_ON_BOOT
|
||||
NODE_STATE(ksCurTime) = getCurrentTime();
|
||||
__atomic_thread_fence(__ATOMIC_ACQ_REL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,6 +132,7 @@ VISIBLE void boot_node(void)
|
|||
fail("boot_node failed for some reason :(\n");
|
||||
}
|
||||
|
||||
clock_sync_test();
|
||||
smp_aps_index++;
|
||||
|
||||
/* grab BKL before leaving the kernel */
|
||||
|
|
|
|||
|
|
@ -553,6 +553,26 @@ BOOT_CODE tcb_t *create_initial_thread(cap_t root_cnode_cap, cap_t it_pd_cap, vp
|
|||
return tcb;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SMP_CLOCK_SYNC_TEST_ON_BOOT
|
||||
BOOT_CODE void clock_sync_test(void)
|
||||
{
|
||||
ticks_t t, t0;
|
||||
ticks_t margin = usToTicks(1) + getTimerPrecision();
|
||||
|
||||
assert(getCurrentCPUIndex() != 0);
|
||||
t = NODE_STATE_ON_CORE(ksCurTime, 0);
|
||||
do {
|
||||
/* perform a memory acquire to get new values of ksCurTime */
|
||||
__atomic_thread_fence(__ATOMIC_ACQUIRE);
|
||||
t0 = NODE_STATE_ON_CORE(ksCurTime, 0);
|
||||
} while (t0 == t);
|
||||
t = getCurrentTime();
|
||||
printf("clock_sync_test[%d]: t0 = %"PRIu64", t = %"PRIu64", td = %"PRIi64"\n",
|
||||
(int)getCurrentCPUIndex(), t0, t, t - t0);
|
||||
assert(t0 <= margin + t && t <= t0 + margin);
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOT_CODE void init_core_state(tcb_t *scheduler_action)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_FPU
|
||||
|
|
|
|||
Loading…
Reference in a new issue