[Kimchi-devel] [PATCH v3] [Kimchi 1/2] Add multi-function field in PCI information

Jose Ricardo Ziviani joserz at linux.vnet.ibm.com
Fri Dec 11 12:49:35 UTC 2015


 - This commit adds a new field in the PCI device data structure to
   notify the client that such PCI is a multi-function device. The
   goal is to make it easy to identify whether a given device is
   multi-function or not in the client side.

Signed-off-by: Jose Ricardo Ziviani <joserz at linux.vnet.ibm.com>
---
 docs/API.md         |  1 +
 model/host.py       | 33 ++++++++++++++++++++++++++++++++-
 model/vmhostdevs.py |  3 ++-
 3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/docs/API.md b/docs/API.md
index 1c4ee50..9593f6b 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -870,6 +870,7 @@ List of available groups.
         * description: Product description of a "pci" device.
     * iommuGroup: IOMMU group number of a "pci" device. Would be None/null if
 	              host does not enable IOMMU support.
+    * multifunction: True if the device belongs to a multi-function adapter.
 
 
 ### Sub-collection: VMs with the device assigned.
diff --git a/model/host.py b/model/host.py
index 628ae71..583accd 100644
--- a/model/host.py
+++ b/model/host.py
@@ -18,6 +18,7 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 
 import libvirt
+from collections import defaultdict
 from lxml import objectify
 
 from wok.exception import InvalidParameter
@@ -144,6 +145,27 @@ class DevicesModel(object):
 class DeviceModel(object):
     def __init__(self, **kargs):
         self.conn = kargs['conn']
+        self.iommu_groups = self._get_iommu_groups()
+
+    def _get_iommu_groups(self):
+        iommu_groups = defaultdict(list)
+        conn = self.conn
+
+        try:
+            devices = DevicesModel(conn=conn).get_list()
+
+        except:
+            return iommu_groups
+
+        for device in devices:
+            info = hostdev.get_dev_info(
+                conn.get().nodeDeviceLookupByName(device))
+            if 'iommuGroup' not in info:
+                continue
+            iommu_group_nr = int(info['iommuGroup'])
+            iommu_groups[iommu_group_nr].append(device)
+
+        return iommu_groups
 
     def lookup(self, nodedev_name):
         conn = self.conn.get()
@@ -151,7 +173,16 @@ class DeviceModel(object):
             dev = conn.nodeDeviceLookupByName(nodedev_name)
         except:
             raise NotFoundError('KCHHOST0003E', {'name': nodedev_name})
-        return hostdev.get_dev_info(dev)
+
+        info = hostdev.get_dev_info(dev)
+        info['multifunction'] = self.is_multifunction_pci(info)
+        return info
+
+    def is_multifunction_pci(self, info):
+        if 'iommuGroup' not in info:
+            return False
+        iommu_group_nr = int(info['iommuGroup'])
+        return len(self.iommu_groups[iommu_group_nr]) > 1
 
     @staticmethod
     def _toint(num_str):
diff --git a/model/vmhostdevs.py b/model/vmhostdevs.py
index c4fb815..de52cd8 100644
--- a/model/vmhostdevs.py
+++ b/model/vmhostdevs.py
@@ -279,7 +279,8 @@ class VMHostDevModel(object):
                 return {'name': dev_name,
                         'type': e.attrib['type'],
                         'product': dev_info.get('product', None),
-                        'vendor': dev_info.get('vendor', None)}
+                        'vendor': dev_info.get('vendor', None),
+                        'multifunction': dev_info.get('multifunction', None)}
 
         raise NotFoundError('KCHVMHDEV0001E',
                             {'vmid': vmid, 'dev_name': dev_name})
-- 
1.9.1




More information about the Kimchi-devel mailing list