[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH 2/4 v3] pci: Add helper functions for sriov devices



On 08/16/2011 12:28 AM, Roopa Prabhu wrote:
From: Roopa Prabhu<roprabhu cisco com>

This patch adds the following helper functions:
pciDeviceIsVirtualFunction: Function to check if a pci device is a sriov VF
pciGetVirtualFunctionIndex: Function to get the VF index of a sriov VF
pciDeviceNetName: Function to get the network device name of a pci device
pciConfigAddressCompare: Function to compare pci config addresses

Signed-off-by: Roopa Prabhu<roprabhu cisco com>
Signed-off-by: Christian Benvenuti<benve cisco com>
Signed-off-by: David Wang<dwang2 cisco com>
---
  src/util/pci.c |  146 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  src/util/pci.h |    8 +++
  2 files changed, 154 insertions(+), 0 deletions(-)


diff --git a/src/util/pci.c b/src/util/pci.c
index c3f3bb4..099c9d3 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -1685,6 +1685,19 @@ int pciDeviceIsAssignable(pciDevice *dev,
      return 1;
  }

+/*
+ * returns 0 if equal and 1 if not
Returns 1 if equal and 0 if not.
+ */
+static int
+pciConfigAddressEqual(struct pci_config_address *bdf1,
+                      struct pci_config_address *bdf2)
+{
+    return ((bdf1->domain == bdf2->domain)&
+            (bdf1->bus == bdf2->bus)&
+            (bdf1->slot == bdf2->slot)&
+            (bdf1->function == bdf2->function));
+}
Please use '&&' rather than '&'.
  static int
  logStrToLong_ui(char const *s,
                  char **end_ptr,
@@ -1889,6 +1902,112 @@ out:

      return ret;
  }
+
+/*
+ * Returns 1 if vf device is a virtual function, 0 if not, -1 on error
+ */
+int
+pciDeviceIsVirtualFunction(const char *vf_sysfs_device_link)
+{
+    char *vf_sysfs_physfn_link = NULL;
+    int ret = -1;
+
+    if (virAsprintf(&vf_sysfs_physfn_link, "%s/physfn",
+        vf_sysfs_device_link)<  0) {
+        virReportOOMError();
+        return ret;
+    }
+
+    ret = virFileExists(vf_sysfs_physfn_link);
+
+    VIR_FREE(vf_sysfs_physfn_link);
+
+    return ret;
+}
+
+/*
+ * Returns the sriov virtual function index of vf given its pf
+ */
+int
+pciGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
+                           const char *vf_sysfs_device_link,
+                           int *vf_index)
+{
+    int ret = -1, i;
+    unsigned int num_virt_fns = 0;
+    struct pci_config_address *vf_bdf = NULL;
+    struct pci_config_address **virt_fns = NULL;
+
+    if (pciGetPciConfigAddressFromSysfsDeviceLink(vf_sysfs_device_link,
+&vf_bdf))
+        return ret;
+
+    if (pciGetVirtualFunctions(pf_sysfs_device_link,&virt_fns,
+&num_virt_fns)) {
+        pciReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Error getting physical function's '%s' "
+                      "virtual_functions"), pf_sysfs_device_link);
+        goto out;
+    }
+
+    for (i = 0; i<  num_virt_fns; i++) {
+         if (pciConfigAddressEqual(vf_bdf, virt_fns[i])) {
+             *vf_index = i;
+             ret = 0;
+             break;
+         }
+    }
+
+out:
+
+    /* free virtual functions */
+    for (i = 0; i<  num_virt_fns; i++)
+         VIR_FREE(virt_fns[i]);
+
+    VIR_FREE(vf_bdf);
+
+    return ret;
+}
+
+/*
+ * Returns the network device name of a pci device
+ */
+int
+pciDeviceNetName(char *device_link_sysfs_path, char **netname)
+{
+     char *pcidev_sysfs_net_path = NULL;
+     int ret = -1;
+     DIR *dir = NULL;
+     struct dirent *entry = NULL;
+
+     if (virBuildPath(&pcidev_sysfs_net_path, device_link_sysfs_path,
+         "net") == -1) {
+         virReportOOMError();
+         return -1;
+     }
+
+     dir = opendir(pcidev_sysfs_net_path);
+     if (dir == NULL)
+         goto out;
+
+     while ((entry = readdir(dir))) {
+            if (STREQ(entry->d_name, ".") ||
+                STREQ(entry->d_name, ".."))
+                continue;
+
+            /* Assume a single directory entry */
+            *netname = strdup(entry->d_name);
+            ret = 0;
+            break;
+     }
+
+     closedir(dir);
+
+out:
+     VIR_FREE(pcidev_sysfs_net_path);
+
+     return ret;
+}
  #else
  int
  pciGetPhysicalFunction(const char *vf_sysfs_path,
@@ -1908,4 +2027,31 @@ pciGetVirtualFunctions(const char *sysfs_path,
                     "supported on non-linux platforms"));
      return -1;
  }
+
+int
+pciDeviceIsVirtualFunction(const char *vf_sysfs_device_link)
+{
+    pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciDeviceIsVirtualFunction is "
+                   "not supported on non-linux platforms"));
+    return -1;
+}
+
+int
+pciGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
+                           const char *vf_sysfs_device_link,
+                           int *vf_index)
+{
+    pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciGetVirtualFunctionIndex is "
+                   "not supported on non-linux platforms"));
+    return -1;
+
+}
+
+int
+pciDeviceNetName(char *device_link_sysfs_path, char **netname)
+{
+    pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciDeviceNetName is not "
+                   "supported on non-linux platforms"));
+    return -1;
+}
  #endif /* __linux__ */
diff --git a/src/util/pci.h b/src/util/pci.h
index fe9479e..a1600fe 100644
--- a/src/util/pci.h
+++ b/src/util/pci.h
@@ -88,4 +88,12 @@ int pciGetVirtualFunctions(const char *sysfs_path,
                             struct pci_config_address ***virtual_functions,
                             unsigned int *num_virtual_functions);

+int pciDeviceIsVirtualFunction(const char *vf_sysfs_device_link);
+
+int pciGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
+                               const char *vf_sysfs_device_link,
+                               int *vf_index);
+
+int pciDeviceNetName(char *device_link_sysfs_path, char **netname);
+
  #endif /* __VIR_PCI_H__ */

ACK with those nits fixed.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]