Pimp My IDE / Garage Dispatch
Back to garage
September 26, 2026 | CPU errata / concurrency / debugging

The atomic instruction lost the update.

A Debian package hung because a shared counter stopped short. The reported cause sat below OpenMP, below the compiler, and inside a Loongson LA664 processor.

The take. When a correct concurrency primitive fails on one processor family, keep descending through the stack. Preserve the source invariant, generated instruction, core placement, neighboring memory traffic, and firmware state.
Build a reproduction card

A package timeout became a hardware report.

Wang Miao hit an infinite loop while packaging Normaliz for Debian on LoongArch. The code processed points in parallel and used OpenMP atomic increments for shared counters. Every point could be marked done while the total counter remained short. The gap changed between runs.[1]

The investigation first checked the source logic and OpenMP implementation. Disassembly showed the compiler had emitted the expected LoongArch amadd.d instruction. Extra std::atomic counters also disagreed. A simple atomic-add loop still refused to fail.[1]

The broken counter needed the right neighboring memory traffic before it would tell the truth.

The trigger was wider than the suspicious line.

The reported minimal case paired relaxed atomic operations with interleaved vectorized memory reads on different physical cores. A vectorized memcpy supplied the missing condition. The authors later found a lower-probability scalar-read trigger for particular address relationships.[1]

The report says the failure affected atomic add, compare-and-swap, max, and swap tests under the same conditions. Operations with a data barrier did not fail in its published trial table. That result belongs to the tested LA664 systems and test setup. It is not a general benchmark for LoongArch or atomic operations.[1]

The contracts above the chip were clear.

OpenMP 5.1 defines an atomic construct with clauses that choose the operation and memory ordering behavior.[2] GCC documents atomic built-ins that map C++ memory-model operations to target instructions and fences.[3]

The LoongArch reference manual says the complete read-modify-write process for AM* instructions is atomic. It also describes AMADD as reading the old value, adding the register value, and writing the result.[4] The reported behavior violated the hardware contract that the compiler and application relied on.

A minimal reproducer is a map of hidden conditions.

  1. Keep the invariant. Record the expected count, observed count, and the rule that says they must match.
  2. Pin the generated instruction. Save compiler version, flags, disassembly, and barrier form.
  3. Pin placement. Record processor model, core IDs, sibling relationships, and thread affinity.
  4. Keep nearby traffic. Preserve copy size, vector width, addresses, alignment, and operations between atomic accesses.
  5. Keep the machine receipt. Save kernel, firmware, microcode, trial count, failure count, and the fix state.

Removing an innocent memcpy would have made the reproducer smaller and false. Good reduction removes noise without deleting the condition that wakes the bug.

The firmware result still needs a host receipt.

The authors reported the issue to Loongson on August 26. They received test firmware on September 9. Their tests on 3A6000 and 3C6000/S systems stopped reproducing the failure after bit 13 of an internal register was set. They reported no single-core loss and a small multi-core cost. Loongson told them a firmware release was expected before October 1.[1]

That is a first-party investigation report about test firmware. Before closing a production incident, identify the public firmware build, install it on the affected host, rerun the pinned reproducer, and keep the before-and-after counts.

Interactive makeover / concurrency reproduction rig

Atomic witness chamber

Traditional purpose replaced: rerun the source test and blame the last layer touched. Better version: pin core placement, instruction form, interleaved reads, and firmware on one copyable reproduction card.

Set the machine conditions

The controls model the conditions reported by the investigation. They do not run code or read your processor.

Thread placement
Atomic instruction form
Reproduction interlocks
TRIGGER MAP OPEN1 / 4 conditions pinned
THREAD A
THREAD B
SHARED COUNTER INVARIANTEXPECTED = OBSERVED / NOT RUN
condition mapone condition pinned

The reported trigger is incomplete.

Pin different physical cores and preserve interleaved reads before comparing instruction forms.

Print the reproduction card

Replace every required marker with host data, commands, disassembly, and observed counts.

Sources read, not vibes

Open the source log
  1. Jia Jie, "One CPU Atomic Instruction, One Packaging Infinite Loop", September 24, 2026. Incident history, source and disassembly investigation, trigger conditions, trial table, impact analysis, workarounds, disclosure dates, and test-firmware result.
  2. OpenMP API Specification 5.1, atomic construct. Atomic-operation and memory-order clauses. This defines the programming contract. It does not verify the processor report.
  3. GCC documentation, atomic built-ins. C++ memory-model mapping, target instruction selection, fences, and memory-order parameters.
  4. LoongArch Reference Manual, atomic memory access instructions. Read-modify-write atomicity, alignment, AMADD behavior, widths, and data-barrier forms.
  5. Normaliz source at commit cdc1a2a6. Current source location for the point counters and OpenMP atomic increments discussed in the incident. This source snapshot was inspected, not executed on LoongArch hardware.
  6. Hacker News discussion 49827900. Exact discovery thread. Comments were not used to verify the hardware claim.

Source boundary. The erratum, trial rates, workaround, and firmware result come from the investigators' report. The OpenMP, GCC, and LoongArch documents establish the expected contracts. Pimp My IDE did not run the reproducer on an LA664 system or verify a public firmware release. The witness chamber generates a test card. It performs no hardware test.