Skip to content

mm: implement the membarrier(2) syscall - #1414

Closed
gburd wants to merge 1 commit into
cloudius-systems:masterfrom
gburd:pr/membarrier
Closed

mm: implement the membarrier(2) syscall#1414
gburd wants to merge 1 commit into
cloudius-systems:masterfrom
gburd:pr/membarrier

Conversation

@gburd

@gburd gburd commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

What

Implements the membarrier(2) syscall, which was missing entirely (not in the
syscall table, no libc entry, no prototype). Runtimes that use it for cheap
asymmetric synchronization (Go, .NET, some JVMs, RCU-style user libraries) could
not use it on OSv.

How

OSv is a single process whose threads all share one address space, so a "global"
and a "private" membarrier are equivalent here. The expedited barrier forces
every other CPU through an IPI: mmu::flush_tlb_all() already broadcasts an IPI
and waits for each CPU to run its handler (a full memory barrier on that CPU),
and we add a local seq_cst fence. This is a correct superset of what
membarrier promises (it also flushes TLBs, which is harmless), and reuses a
proven, arch-portable primitive rather than adding a dedicated per-arch IPI (x64
inter_processor_interrupt vs aarch64 sgi_interrupt). A lighter dedicated IPI
can replace it if membarrier ever shows up hot in a profile.

  • MEMBARRIER_CMD_QUERY returns the supported command mask.
  • REGISTER_{GLOBAL,PRIVATE}_EXPEDITED are accepted as no-ops (any thread may
    issue the barrier).
  • {GLOBAL, GLOBAL_EXPEDITED, PRIVATE_EXPEDITED} run the barrier.
  • SYNC_CORE / RSEQ / CPU-flag variants and unknown commands return EINVAL,
    as does a nonzero flags argument.

Wired as syscall SYS_membarrier (adding __NR_membarrier / SYS_membarrier
for x86-64) with a tracepoint, plus the sys/membarrier.h header with the
command enum and prototype, and the symbol exported from libc.so.6 and
ld-musl.so.1.

Testing

tests/tst-membarrier.cc covers QUERY, register, the three barrier commands,
and the EINVAL paths. Passes on OSv under KVM with 1, 2 and 4 vCPUs (exercising
the cross-CPU IPI broadcast).

membarrier() was missing entirely: not in the syscall table, no libc entry,
no prototype. Runtimes that rely on it for cheap asymmetric synchronization
(Go, .NET, some JVMs and RCU-style user libraries) could not use it.

OSv is a single process whose threads all share one address space, so a
"global" and a "private" membarrier are equivalent here. Implement the
expedited barrier by forcing every other CPU through an IPI: mmu::flush_tlb_all()
already broadcasts an IPI and waits for each CPU to run its handler, which is a
full memory barrier on that CPU, and we add a local seq_cst fence. This is a
correct superset of what membarrier promises (it also flushes TLBs, which is
harmless), and it reuses a proven, arch-portable primitive rather than adding a
dedicated per-arch IPI (x64 inter_processor_interrupt vs aarch64 sgi_interrupt).
A lighter dedicated IPI can replace it if membarrier ever shows up hot.

- MEMBARRIER_CMD_QUERY returns the supported command mask.
- REGISTER_{GLOBAL,PRIVATE}_EXPEDITED are accepted as no-ops (any thread may
  issue the barrier).
- {GLOBAL, GLOBAL_EXPEDITED, PRIVATE_EXPEDITED} run the barrier.
- SYNC_CORE / RSEQ / CPU-flag variants and unknown commands return EINVAL,
  as does a nonzero flags argument.

Wire it as syscall SYS_membarrier (adding __NR_membarrier / SYS_membarrier for
x86-64) with a tracepoint, add the sys/membarrier.h header with the command
enum and prototype, and export the symbol from libc.so.6 and ld-musl.so.1.

Add tests/tst-membarrier.cc covering QUERY, register, the three barrier
commands, and the EINVAL paths. Passes on OSv under KVM with 1, 2 and 4 vCPUs
(exercising the cross-CPU IPI broadcast).
@gburd gburd closed this Jul 13, 2026
@gburd
gburd deleted the pr/membarrier branch July 13, 2026 11:18
@gburd

gburd commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #1434 (rebased onto current master; GitHub auto-closed this one when the branch was updated). Please review #1434 instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant