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

Reply via email to