vGPU¶
Everything the virtualization.vgpu block of a profile means: how a GPU
becomes a vGPU host or a vGPU guest, the fields each side takes, what NVML and
nvidia-smi report for them, and what is refused at load.
This is a reference. For installing a host or a guest node and reading it back
with nvidia-smi, see the vGPU host and guest guide;
for the rest of a profile, Configuration.
What it simulates¶
NVIDIA vGPU splits a physical GPU into virtual GPUs that a hypervisor hands to
virtual machines (VMs). Two drivers are involved, and each sees something
different. The host is the hypervisor's physical GPU, running the vGPU
manager and the vGPU instances carved from it. The guest is the vGPU as
the VM sees it: a GPU that knows it is virtual, which host driver it runs on,
and whether it holds a vGPU software license. Mokka simulates either view at
the driver level, so nvidia-smi and go-nvml consumers read it as they would
on a real hypervisor or VM. No hypervisor or VM is involved.
Choosing a side¶
device_defaults.virtualization.mode selects what NVML reports:
mode |
nvmlDeviceGetVirtualizationMode |
What else changes |
|---|---|---|
none |
NVML_GPU_VIRTUALIZATION_MODE_NONE |
Nothing: bare metal. Every shipped profile declares it |
passthrough |
NVML_GPU_VIRTUALIZATION_MODE_PASSTHROUGH |
Nothing else |
vgpu |
NVML_GPU_VIRTUALIZATION_MODE_VGPU |
With a guest block: licensing, and the PCI capability GFD reads |
host_vgpu |
NVML_GPU_VIRTUALIZATION_MODE_HOST_VGPU |
The host types and running instances |
nvidia-smi -q prints the two vGPU modes as VGPU and Host VGPU. An
unrecognised mode reports NONE and ignores the vgpu block.
vGPU is configured in device_defaults only: a
per-device override does not merge
virtualization, so every GPU on the node starts on the same side. Only a
runtime override can move one GPU to another.
Under the chart¶
The chart sets the block from gpu.vgpu, so an install names neither the
NVML mode nor the profile key:
gpu.vgpu |
Default | Meaning |
|---|---|---|
mode |
"" |
host renders mode: host_vgpu, guest renders mode: vgpu, "" leaves the profile's block untouched |
hostVgpuMode |
sriov |
Host only. Becomes host_vgpu_mode |
types |
[] |
Host only. The types, in the profile's snake_case form |
instances |
[] |
Host only. The running instances |
guest |
{} |
Guest only. The guest block, in the profile's snake_case form |
mode: host passes only hostVgpuMode, types and instances; mode: guest
passes only guest. The chart ignores the other mode's fields rather than
refusing them. mode: guest with an empty guest renders mode: vgpu and no
vgpu block, which is the mode-only guest. The chart
refuses to render mode: host with no types or with gpu.mig.enabled; every
other rule is the node agent's, which validates the rendered
block.
Runtime overrides¶
nvml-mock-ctl set can change
virtualization on a running node, for one GPU or for all of them. An override
is not validated like the profile: only its field names and value types are
checked, not the validation rules. A GPU set to host_vgpu with
no vgpu block, for example, reports Host VGPU as its mode and answers
NVML_ERROR_NOT_SUPPORTED to every vGPU call. The guest's PCI capability is
written by the node agent from the profile, so an override does not change it.
Toggling a guest's license works:
The next nvidia-smi -q reports GPU 0 unlicensed.
Host¶
device_defaults:
virtualization:
mode: "host_vgpu"
host_vgpu_mode: "sriov" # sriov, non_sriov
vgpu:
types:
- id: 474
name: "NVIDIA A100-4C"
framebuffer_mib: 4096
max_instances: 10
license: "NVIDIA-Virtual-Compute-Server,9.0"
instances:
- type: "NVIDIA A100-4C"
count: 2
No profile ships a type list. Which types a board offers depends on the vGPU software release, not on the silicon, so an install declares its own, taking the IDs, names and sizes from that release's documentation.
host_vgpu_mode is required: sriov or non_sriov. nvidia-smi -q prints it
as Host VGPU Mode.
Types¶
| Field | Default | Meaning |
|---|---|---|
id |
required | The vGPU type ID NVML hands out. Non-zero, unique within the list. A type ID names the same type on every GPU |
name |
required | What nvidia-smi vgpu prints, e.g. NVIDIA A100-4C. Unique within the list; instances refer to it |
framebuffer_mib |
required | Framebuffer per instance, non-zero |
max_instances |
required | How many instances of this type one GPU holds, 1–999 |
class |
Compute |
The type's class string |
max_instances_per_vm |
1 |
Instances one VM may hold |
license |
"" |
The license string the type requires |
num_display_heads |
1 |
Display heads |
resolution |
{width: 4096, height: 2160} |
Maximum resolution, reported for every display head |
frame_rate_limit |
0 |
Frame-rate limit |
gpu_instance_profile_id |
not MIG-backed (0xFFFFFFFF) |
The MIG GPU instance profile behind the type |
device_id |
the board's pci.device_id |
The PCI device and vendor ID the type presents to its guest, encoded as in the profile's pci block |
subsystem_id |
the board's pci.subsystem_id |
The PCI subsystem and subsystem vendor ID the type presents to its guest |
The two PCI IDs are what nvmlVgpuTypeGetDeviceID reports. NVML reports them
per type rather than per board, so each can be set per type; one left unset
takes the board's.
Instances¶
Each entry asks for count running instances of the named type. An omitted
count means one. Instances run from the moment the library loads; no NVML call
creates or destroys them, and only a runtime override of
instances changes the set.
A GPU runs one vGPU type at a time, so every entry names the same type, and
their counts together are bounded by that type's max_instances. When the
profile sets memory.total_bytes, their framebuffer together must fit it.
Host identities¶
An instance's ID is (GPU index + 1) × 1000 + slot + 1, where the slot counts
the GPU's instances from zero in declaration order: GPU 0's first instance is
1001, GPU 1's second is 2002. The GPU index is the GPU's physical index on
the node, not the enumeration index a container sees: in a container given only
GPU 3, that GPU's first instance is still 4001. The ID encodes its GPU, so it
is the same in every process.
Each instance's vGPU UUID and VM UUID are derived from its GPU's UUID and slot.
They are stable across restarts when the profile declares devices[].uuid,
which every shipped profile does.
Every instance runs in a VM of its own. The VM name is blank. The guest driver
version is Not Available, which is what NVML reports until a driver loads in
the VM, and no simulated VM loads one; nvidia-smi prints it as N/A. ECC
mode follows the board's
ecc.mode_current, and the GPU
instance ID is not MIG-backed, which nvidia-smi prints as N/A.
Host behaviour¶
Supported and creatable types. nvidia-smi vgpu -s lists every declared
type. nvidia-smi vgpu -c lists what could still be created: every declared
type while no instance runs, then only the running type until the GPU holds
max_instances of it, then nothing.
Idle instances. No process runs in a simulated guest, so every instance reports no framebuffer used, no encoder or frame buffer capture (FBC) sessions, and accounting disabled. Each reports itself licensed, with a permanent license.
Not implemented, N/A. These calls return NVML_ERROR_NOT_SUPPORTED, which
nvidia-smi prints as N/A: an instance's placement ID, mdev UUID, accounting
PIDs, utilization and guest PCI bus ID; a type's BAR1 info, capabilities,
placements and maximum instances per GPU instance; and the device's vGPU
capabilities, vGPU driver capabilities and heterogeneous mode.
Errors. A host-side vGPU call on a GPU that is not in host_vgpu mode
returns NVML_ERROR_NOT_SUPPORTED, as a bare-metal driver does, and
nvidia-smi vgpu prints No supported devices in vGPU mode. An unknown type
ID returns NVML_ERROR_INVALID_ARGUMENT. For an instance ID, NVML reserves
NVML_ERROR_INVALID_ARGUMENT for 0; any other ID that matches no running
instance, including one on a GPU the caller cannot see, returns
NVML_ERROR_NOT_FOUND. The vGPU calls answer
from configuration and do not advance
failure injection's call counter. A call that
takes a device handle or an instance ID reports the loss once failure injection
has made that GPU lost; a call that takes only a type ID answers from any other
GPU that declares the type.
nvidia-smi pmon declines a host GPU, printing The feature is not
supported in this configuration for each one, as it does on a hypervisor.
Guest¶
device_defaults:
virtualization:
mode: "vgpu"
vgpu:
guest:
host_driver_version: "550.163.01"
host_driver_branch: "r550_00"
license:
product: "NVIDIA Virtual Compute Server"
state: "licensed" # licensed, unlicensed
expiry: "2027-01-01T00:00:00Z"
| Field | Default | Meaning |
|---|---|---|
host_driver_version |
required | The host's vGPU manager version. At most 10 bytes |
host_driver_branch |
required | The host driver's branch. At most 10 bytes |
license |
absent: unlicensed | The vGPU software license the guest holds |
license.product |
"" |
The licensed product name. At most 127 bytes |
license.state |
licensed |
licensed or unlicensed |
license.expiry |
absent: permanent | When a licensed guest's license expires, as an RFC 3339 time |
The two host driver fields are limited to 10 bytes because that is the width of the fields in the PCI capability that carries them.
What changes for a guest:
nvidia-smi -qprintsVirtualization Mode : VGPUand avGPU Software Licensed Productsection with the product and itsLicense Status, such asLicensed (Expiry: Permanent). An unlicensed guest reports the unlicensed state and no expiry.- The node agent writes the vGPU vendor capability, holding the host driver
version and branch, into each GPU's config space in its
PCI sysfs tree. GPU Feature
Discovery (GFD) reads it from there and labels the node
nvidia.com/vgpu.present,nvidia.com/vgpu.host-driver-versionandnvidia.com/vgpu.host-driver-branch.
Licensing is reported through nvmlDeviceGetGridLicensableFeatures (v4, which
the unversioned name resolves to); a GPU that is not a guest with a guest
block answers NVML_ERROR_NOT_SUPPORTED.
A guest with no block¶
mode: vgpu with no guest block reports Virtualization Mode : VGPU and
nothing else: no PCI capability, and licensing answers
NVML_ERROR_NOT_SUPPORTED.
Validation¶
The block is checked when the config loads, and each failure names the field:
host_vgpuneedshost_vgpu_modeset tosriovornon_sriov, and at least one type.- Every type needs a non-zero
id, anameand a non-zeroframebuffer_mib, withmax_instancesbetween 1 and 999. No two types share anidor aname. - Every instance names a declared type, and its
countis not negative. - All instances name the same type.
- The instances' total count does not exceed that type's
max_instances. - When the profile sets
memory.total_bytes, the instances' total framebuffer does not exceed it. guestis refused underhost_vgpu;typesandinstancesare refused undervgpu.- A host runs no GPU in MIG mode:
host_vgpuis refused whendevice_defaults.migor any per-devicemigblock setsmode_current: enabled, andnvmlDeviceSetMigModerefuses to enable MIG on a host withNVML_ERROR_NOT_SUPPORTED. A real host with MIG on runs only MIG-backed types, which are not simulated. - A
guestblock needshost_driver_versionandhost_driver_branch, each at most 10 bytes. license.stateislicensedorunlicensed,license.productis at most 127 bytes, andlicense.expiryparses as RFC 3339.
Any other mode ignores the vgpu block, which is why the host_vgpu_mode:
"N/A" every shipped profile carries loads.
The node agent refuses an invalid block and does not become ready, logging the
field as a state source error. The library rejects the same config and falls
back to its built-in defaults with a warning.
Not simulated
- The host's mdev and SR-IOV sysfs surfaces.
- MIG-backed vGPU types, and so a host with MIG mode on.
- Creating or destroying instances at runtime.
- Shipped vGPU type catalogues: an install declares its types.
- Charging the instances' framebuffer against the physical GPU's memory.
- Scheduler, placement and heterogeneous-mode APIs.
nvmlGetVgpuVersionandnvmlSetVgpuVersion.- vGPU metadata and migration compatibility.
- Every
Set*call. nvmlDeviceGetGridLicensableFeaturesv1–v3.- KubeVirt or any other VM manager.