PARAVIRT_MEMBAR_SYNC(9)
π NAME π
okay bestie, meet paravirt_membar_sync β literally the memory barrier for paravirtualized device drivers β¨. This little icon is PARAVIRT_MEMBAR_SYNC(9) from the Kernel Developer's Manual, and yes she understood the assignment π
.
π¦ SYNOPSIS π¦
#include <sys/paravirt_membar.h>
void
paravirt_membar_sync(void);
πΈ DESCRIPTION πΈ
The paravirt_membar_sync function issues a store-before-load barrier for coordination with a paravirtualized device. Periodt.
This function has the same ordering semantics as membar_sync(3), but hear me out: membar_sync(3) can only coordinate with other CPUs that NetBSD is running on. In a virtual machine, NetBSD may be running on a single virtual CPU, and patch membar_sync(3) to be a no-op π« β while the host side of a paravirtualized device may be running on a different physical CPU requiring a barrier that membar_sync(3) does not issue. So yeah, that's the whole vibe, no cap.
β¨ EXAMPLES β¨
Submit a request to the host device, and notify the host to process itβbut elide the notification, which is expensive, if the host is already reading requests anyway:
/*
* Write the request into the ring buffer.
*/
memcpy(cputodev_ring->buffer[sc->sc_cputodev_idx], request,
sizeof(*request));
/*
* Publish the request to the host device side.
*/
cputodev_ring->header->producer_tail = ++sc->sc_cputodev_idx;
/*
* Ensure we have published it _before_ we check whether the
* host needs notification.
*/
paravirt_membar_sync();
/*
* Notify the host, if needed. Notifying the host is usually
* expensive (trap to hypervisor), so we try to avoid it if not
* needed.
*/
if (cputodev_ring->header->needs_notification)
notify_host();
Enable interrupts from the host and check whether any were pending while interrupts were disabled:
/*
* Tell the host device to deliver interrupts after this
* point.
*/
restart:
devtocpu_ring->header->needs_notification = true;
/*
* Ensure we have requested interrupts _before_ we check
* whether we missed any notifications.
*/
paravirt_membar_sync();
/*
* Check whether there were any pending notifications while
* interrupts were blocked. If not, stop here.
*/
idx = devtocpu_ring->header->producer_idx;
if (sc->sc_devtocpu_idx == idx)
return;
/*
* Process the notifications.
*/
devtocpu_ring->header->needs_notification = false;
while (sc->sc_devtocpu_idx != idx) {
struct buffer *buf =
devtocpu_ring->buffer[sc->sc_devtocpu_idx];
process_notification(buf);
sc->sc_devtocpu_idx++;
sc->sc_devtocpu_idx %= ringlen;
}
goto restart;
N.B.: Other ordering or bouncing may be required withbus_dmamap_sync(9); this is independent ofparavirt_membar_sync, which is needed in addition tobus_dmamap_sync(9)to guarantee store-before-load ordering when there is no intervening I/O doorbell trigger for a DMA operation, nor interrupt delivery for a DMA completion.
π SEE ALSO π
membar_ops(3)bus_dma(9)bus_space(9)
π HISTORY π
These atomic operations first appeared in NetBSD 12.0.
mwah π β this page is from Debian, dated August 31, 2025, and the manual name is PARAVIRT_MEMBAR_SYNC(9). go be iconic with your barriers π
π¦ where this page comes from
- nixpkgs unstable: netbsd-source 11.0
- Copyright (c) 2025 The NetBSD Foundation
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms