Control: tags -1 + patch
Hi,
The "hang" is actually a deadlock. A memory-ordering race in the
single producer/consumer queue makes the producer thread give up early.
Running sphsinglepcqueue_ttt under gdb on an arm64 buildd (Neoverse-N1)
with a watchdog showed:
test_thread_Producer_fill SPHSinglePCQueueAllocStrideEntry (0x4000100000)
failed
The producer thread exited with an error after this. The consumer thread
was at item ~70k of 14.5M, spinning in lfPCQentry_verify() ->
sched_yield() waiting for entries that will never come, and main() was
blocked in pthread_join(). So the build sits there until the buildd
kills it.
Root cause: arm and aarch64 have no sasatom_<arch>.h and use
sasatom_generic.h. There, sas_read_barrier(), sas_write_barrier() and
sas_full_barrier() are compiler-only barriers (asm("" ::: "memory")).
On a weakly ordered CPU this race is possible:
consumer (SPHSinglePCQueueFreeNextEntry):
entry->header = 0; sas_write_barrier(); qtail = next;
producer (SPHSinglePCQueueFull, then SPHSinglePCQueueAllocStrideEntry):
reads the new qtail -> "not full"
reads entry->header -> still sees the stale "allocated" bit
-> alloc returns NULL, which the test treats as fatal
x86_64 and powerpc use real fences, which is why they are not affected.
Upstream already fixed this for the architectures it added later:
sasatom_riscv.h and sasatom_loongarch.h on master use
__sync_synchronize(). arm was never covered.
The attached patch:
- makes the generic barriers __atomic_thread_fence(__ATOMIC_SEQ_CST),
which is "dmb ish" on arm64 and matches x86_64
- in the alloc functions that can fail (AllocStrideEntry,
AllocStrideTimeStamped, AllocStrideDirect), loads qtail and adds a
barrier before reading the entry header
- adds the missing barrier in SPHSinglePCQueueGetNextComplete between
the valid-flag check and the caller's payload reads
(SPHSinglePCQueueGetNextCompleteDirect already has one)
Without the patch, sphsinglepcqueue_ttt hangs on arm64 and armhf every
time. With it, the full test suite passes (20/20) on both in an Ubuntu
PPA, with sphsinglepcqueue_ttt finishing in a few minutes.
I've also sent that upstream, https://github.com/sphde/sphde/pull/76
Cheers,
Sebastien