[libvirt] [PATCH 4/6] node_device: new functions to get sriov/iommu info from sysfs

Laine Stump laine at laine.org
Fri May 15 15:04:27 UTC 2015


The udev and hal drivers both already call the same functions as these
new functions added to node_device_linux_sysfs.c, but 1) we need to
call them from node_device_driver.c, and 2) it would be nice to
eliminate the duplicated code from the hal and udev backends.
---
 src/node_device/node_device_linux_sysfs.c | 90 +++++++++++++++++++++++++++++++
 src/node_device/node_device_linux_sysfs.h |  2 +
 2 files changed, 92 insertions(+)

diff --git a/src/node_device/node_device_linux_sysfs.c b/src/node_device/node_device_linux_sysfs.c
index fc82b32..6d5a406 100644
--- a/src/node_device/node_device_linux_sysfs.c
+++ b/src/node_device/node_device_linux_sysfs.c
@@ -137,6 +137,96 @@ nodeDeviceSysfsGetSCSIHostCaps(virNodeDevCapDataPtr d)
     return ret;
 }
 
+
+static int
+nodeDeviceSysfsGetPCISRIOVCaps(const char *sysfsPath,
+                               virNodeDevCapDataPtr data)
+{
+    size_t i;
+    int ret;
+
+    /* this could be a refresh, so clear out the old data */
+    for (i = 0; i < data->pci_dev.num_virtual_functions; i++)
+       VIR_FREE(data->pci_dev.virtual_functions[i]);
+    VIR_FREE(data->pci_dev.virtual_functions);
+    data->pci_dev.num_virtual_functions = 0;
+    data->pci_dev.flags &= ~VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION;
+    data->pci_dev.flags &= ~VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION;
+
+    if (!virPCIGetPhysicalFunction(sysfsPath, &data->pci_dev.physical_function))
+        data->pci_dev.flags |= VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION;
+
+    ret = virPCIGetVirtualFunctions(sysfsPath, &data->pci_dev.virtual_functions,
+                                    &data->pci_dev.num_virtual_functions);
+    if (ret < 0)
+        return ret;
+
+    if (data->pci_dev.num_virtual_functions > 0)
+        data->pci_dev.flags |= VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION;
+
+    return ret;
+}
+
+
+static int
+nodeDeviceSysfsGetPCIIOMMUGroupCaps(virNodeDevCapDataPtr data)
+{
+    size_t i;
+    int tmpGroup, ret = -1;
+    virPCIDeviceAddress addr;
+
+    /* this could be a refresh, so clear out the old data */
+    for (i = 0; i < data->pci_dev.nIommuGroupDevices; i++)
+       VIR_FREE(data->pci_dev.iommuGroupDevices[i]);
+    VIR_FREE(data->pci_dev.iommuGroupDevices);
+    data->pci_dev.nIommuGroupDevices = 0;
+    data->pci_dev.iommuGroupNumber = 0;
+
+    addr.domain = data->pci_dev.domain;
+    addr.bus = data->pci_dev.bus;
+    addr.slot = data->pci_dev.slot;
+    addr.function = data->pci_dev.function;
+    tmpGroup = virPCIDeviceAddressGetIOMMUGroupNum(&addr);
+    if (tmpGroup == -1) {
+        /* error was already reported */
+        goto cleanup;
+    }
+    if (tmpGroup == -2) {
+        /* -2 return means there is no iommu_group data */
+        ret = 0;
+        goto cleanup;
+    }
+    if (tmpGroup >= 0) {
+        if (virPCIDeviceAddressGetIOMMUGroupAddresses(&addr, &data->pci_dev.iommuGroupDevices,
+                                                      &data->pci_dev.nIommuGroupDevices) < 0)
+            goto cleanup;
+        data->pci_dev.iommuGroupNumber = tmpGroup;
+    }
+
+    ret = 0;
+ cleanup:
+    return ret;
+}
+
+
+/* nodeDeviceSysfsGetPCIRelatedCaps() get info that is stored in sysfs
+ * about devices related to this device, i.e. things that can change
+ * without this device itself changing. These must be refreshed
+ * anytime full XML of the device is requested, because they can
+ * change with no corresponding notification from the kernel/udev.
+ */
+int
+nodeDeviceSysfsGetPCIRelatedDevCaps(const char *sysfsPath,
+                                    virNodeDevCapDataPtr data)
+{
+    if (nodeDeviceSysfsGetPCISRIOVCaps(sysfsPath, data) < 0)
+        return -1;
+    if (nodeDeviceSysfsGetPCIIOMMUGroupCaps(data) < 0)
+        return -1;
+    return 0;
+}
+
+
 #else
 
 int
diff --git a/src/node_device/node_device_linux_sysfs.h b/src/node_device/node_device_linux_sysfs.h
index 307a8aa..e4afdd7 100644
--- a/src/node_device/node_device_linux_sysfs.h
+++ b/src/node_device/node_device_linux_sysfs.h
@@ -26,5 +26,7 @@
 # include "node_device_conf.h"
 
 int nodeDeviceSysfsGetSCSIHostCaps(virNodeDevCapDataPtr d);
+int nodeDeviceSysfsGetPCIRelatedDevCaps(const char *sysfsPath,
+                                        virNodeDevCapDataPtr data);
 
 #endif /* __VIR_NODE_DEVICE_LINUX_SYSFS_H__ */
-- 
2.1.0




More information about the libvir-list mailing list