homi#

homi, Host-Orchestrated Multi-process I/O, opens a set of NVMe devices and holds them open until it is told to stop. It does no I/O of its own.

Its purpose is to provide the long-lived primary process for uPCIe (multi-process). The primary owns the DMA hugepages and the controller hardware state, and it must outlive every secondary attached to it. Running homi puts that responsibility in a process of its own, so the processes actually doing I/O can come and go freely as secondaries.

uPCIe (multi-process) is only available for the uPCIe and SPDK backends. homi is therefore useful where one of those is built: upcie on Linux, and spdk on Linux and FreeBSD. On Windows it exits with -ENOTSUP, since no multi-process capable backend is available there. On other platforms it runs, but opening a device with a non-zero shm_id fails with -ENOTSUP.

start — Hold devices open#

Opens every device given as a positional argument, then blocks until signalled.

--shm_id is required and sets the shared-memory id the devices are opened with. Every process that should share these controllers must be started with the same id. --be optionally selects the backend.

Roles are not assigned by the tool: whichever process claims a given shm_id first becomes the primary (see Process model). Starting homi before any secondary is therefore what makes it the primary.

--host_heap_size sets the size of the upcie host DMA heap, in bytes. The heap is allocated once per process, on the first device open, so this value covers every device homi holds rather than being per device.

Rather than the 1 GiB the backend would otherwise use, homi defaults to 16 MiB per device held. It needs only the admin queue and the sync queue pair that opening a device creates, and each of those carries a request pool costing 4 MiB — so 16 MiB per device is roughly double what is required. Every process in multi-process mode allocates a heap of its own, so a primary claiming the backend default would leave nothing in the hugepage pool for the secondaries it exists to serve:

homi start 0000:03:00.0 --be upcie --shm_id 1 --host_heap_size 134217728

If any device fails to open, homi closes the devices it has already opened and exits with an error, rather than holding a partial set open. Once all devices are open it reports that it has started, then waits for SIGINT (Ctrl+C) or SIGTERM. On either signal it closes all devices and exits.

Example — hold a single device open as the primary for shm_id 1:

homi start 0000:03:00.0 --be upcie --shm_id 1

Example — hold several devices under the same shm_id:

homi start 0000:03:00.0 0000:04:00.0 --be upcie --shm_id 1

While it runs, other processes attach as secondaries by passing the same --shm_id:

xnvme info 0000:03:00.0 --be upcie --shm_id 1

Backends#

homi works with any backend that advertises the multi-process capability, which is spdk and upcie:

homi start 0000:03:00.0 --be spdk --shm_id 1

See also

uPCIe (multi-process)

The process model, startup handshake, admin-queue serialization, and the known limitations of multi-process mode.