diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-21 11:30:46 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-21 11:30:46 -0400 |
| commit | 79d86fe350eaa520cda91b3832d30b085d9bcd6f (patch) | |
| tree | f655089c62cff430c6bc1e34e8c14b4ccab41c0c | |
| parent | ad1f7a6a3cd262cc084673ec5cf0c561328ec7c7 (diff) | |
| download | open-iov-79d86fe350eaa520cda91b3832d30b085d9bcd6f.tar.gz open-iov-79d86fe350eaa520cda91b3832d30b085d9bcd6f.zip | |
kernel: Add get_available mdev callback (fix leaked available_instances)
The mdev core's shared parent->available_instances counter leaks whenever
an mdev remove path fails to complete (as happened during the now-fixed
remove crash): creates then fail with -EUSERS while sysfs reports 0
available instances with zero mdevs present.
Implement mdev_driver.get_available to compute availability from the
driver's own authoritative device list instead of the core counter.
Handles the 'nvidia-' prefixed sysfs type names when looking up per-type
max_instances (falls back to 1).
| -rw-r--r-- | kernel/main.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/kernel/main.c b/kernel/main.c index 8ba7083..c96357b 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -65,11 +65,43 @@ struct nv_vgpu_type_info g_vgpu_type_infos[16]; int g_num_vgpu_types = 0; static DEFINE_MUTEX(g_vgpu_type_lock); +/* + * get_available - report available instances for an mdev type. + * + * The mdev core's shared parent->available_instances counter can drift + * (e.g. if a remove path ever fails to complete). Compute availability + * from our own authoritative device list instead. + */ +static unsigned int nv_vgpu_get_available(struct mdev_type *mtype) +{ + struct nv_vgpu_type_info *info; + struct nv_vgpu_device *vgpu; + const char *name = mtype->sysfs_name; + unsigned int active = 0, max = 1; + + /* Type dirs may carry an extra "nvidia-" prefix vs our type names */ + if (str_has_prefix(name, "nvidia-")) + name += strlen("nvidia-"); + info = nv_vgpu_find_type_info(name); + if (info && info->max_instances) + max = info->max_instances; + + mutex_lock(&nv_vgpu_driver.lock); + list_for_each_entry(vgpu, &nv_vgpu_driver.devices, list) { + if (vgpu->mdev && vgpu->mdev->type == mtype) + active++; + } + mutex_unlock(&nv_vgpu_driver.lock); + + return active >= max ? 0 : max - active; +} + struct mdev_driver nv_vgpu_mdev_driver = { .device_api = VFIO_DEVICE_API_PCI_STRING, .max_instances = 8, .probe = nv_vgpu_mdev_create, .remove = nv_vgpu_mdev_remove, + .get_available = nv_vgpu_get_available, .driver = { .name = "nvidia-vgpu-vfio-mdev", }, |
