WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] xend: passthrough: loosen the pci co-assi

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] xend: passthrough: loosen the pci co-assignment for pv guest
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 04 Aug 2009 08:50:23 -0700
Delivery-date: Tue, 04 Aug 2009 08:51:21 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1249212471 -3600
# Node ID 9a5e12b150b52d2ea169a075b61fb4e40d34362d
# Parent  edf21ab7d7a4c16214276ca32f9e5b64fce3418a
xend: passthrough: loosen the pci co-assignment for pv guest

In current xend, we can not assign co-assignment devices to different
guests, even for pv guests. This patch loosens the policy for pv
guest: if none of the co-assignment devices have been assigned to hvm
guest, we can assign the devices to different pv guests.

The patch also adds a detection: if a device has been assigned to
guest, we can't try to "xm pci-attach" it to the same guest again.

Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx>
---
 tools/python/xen/util/pci.py            |   21 ++++++++++++--
 tools/python/xen/xend/XendDomain.py     |    5 ++-
 tools/python/xen/xend/XendDomainInfo.py |   45 +++++++++++++++++---------------
 tools/python/xen/xend/server/pciif.py   |   14 +++++++--
 tools/python/xen/xm/main.py             |   29 +++++++++++++-------
 5 files changed, 74 insertions(+), 40 deletions(-)

diff -r edf21ab7d7a4 -r 9a5e12b150b5 tools/python/xen/util/pci.py
--- a/tools/python/xen/util/pci.py      Sun Aug 02 12:26:23 2009 +0100
+++ b/tools/python/xen/util/pci.py      Sun Aug 02 12:27:51 2009 +0100
@@ -7,6 +7,7 @@
 
 import sys
 import os, os.path
+import errno
 import resource
 import re
 import types
@@ -571,7 +572,7 @@ class PciDeviceParseError(Exception):
     def __init__(self,msg):
         self.message = msg
     def __str__(self):
-        return 'Error Parsing PCI Device Info: '+self.message
+        return self.message
 
 class PciDeviceAssignmentError(Exception):
     def __init__(self,msg):
@@ -880,7 +881,13 @@ class PciDevice:
         os.close(fd)
 
     def detect_dev_info(self):
-        class_dev = self.pci_conf_read16(PCI_CLASS_DEVICE)
+        try:
+            class_dev = self.pci_conf_read16(PCI_CLASS_DEVICE)
+        except OSError, (err, strerr):
+            if err == errno.ENOENT:
+                strerr = "the device doesn't exist?"
+            raise PciDeviceParseError('%s: %s' %\
+                (self.name, strerr))
         pos = self.find_cap_offset(PCI_CAP_ID_EXP)
         if class_dev == PCI_CLASS_BRIDGE_PCI:
             if pos == 0:
@@ -941,7 +948,7 @@ class PciDevice:
                 ', but it is not owned by pciback or pci-stub.'
             raise PciDeviceAssignmentError(err_msg % (pci_dev, self.name))
 
-    def do_FLR(self):
+    def do_FLR(self, is_hvm):
         """ Perform FLR (Functional Level Reset) for the device.
         """
         if self.dev_type == DEV_TYPE_PCIe_ENDPOINT:
@@ -958,6 +965,10 @@ class PciDevice:
                     self.do_FLR_for_integrated_device()
                 else:
                     funcs = self.find_all_the_multi_functions()
+
+                    if not is_hvm and (len(funcs) > 1):
+                        return
+
                     self.devs_check_driver(funcs)
 
                     parent = pci_dict_to_bdf_str(self.find_parent())
@@ -982,6 +993,10 @@ class PciDevice:
                     # Remove the element 0 which is a bridge
                     target_bus = devs[0]
                     del devs[0]
+
+                    if not is_hvm and (len(devs) > 1):
+                        return
+
                     self.devs_check_driver(devs)
 
                     # Do Secondary Bus Reset.
diff -r edf21ab7d7a4 -r 9a5e12b150b5 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Sun Aug 02 12:26:23 2009 +0100
+++ b/tools/python/xen/xend/XendDomain.py       Sun Aug 02 12:27:51 2009 +0100
@@ -423,7 +423,7 @@ class XendDomain:
                     log.exception("Unable to recreate domain")
                     try:
                         xc.domain_pause(domid)
-                        XendDomainInfo.do_FLR(domid)
+                        XendDomainInfo.do_FLR(domid, dom['hvm'])
                         xc.domain_destroy(domid)
                     except:
                         log.exception("Hard destruction of domain failed: %d" %
@@ -1276,7 +1276,8 @@ class XendDomain:
         else:
             try:
                 xc.domain_pause(int(domid))
-                XendDomainInfo.do_FLR(int(domid))
+                dom = self.domains[int(domid)]
+                XendDomainInfo.do_FLR(int(domid), dom.info.is_hvm())
                 val = xc.domain_destroy(int(domid))
             except ValueError:
                 raise XendInvalidDomain(domid)
diff -r edf21ab7d7a4 -r 9a5e12b150b5 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Sun Aug 02 12:26:23 2009 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Sun Aug 02 12:27:51 2009 +0100
@@ -302,7 +302,7 @@ from xen.xend.server.pciif import parse_
     get_assigned_pci_devices, get_all_assigned_pci_devices
 
 
-def do_FLR(domid):
+def do_FLR(domid, is_hvm):
     dev_str_list = get_assigned_pci_devices(domid)
 
     for dev_str in dev_str_list:
@@ -311,7 +311,7 @@ def do_FLR(domid):
         except Exception, e:
             raise VmError("pci: failed to locate device and "+
                     "parse it's resources - "+str(e))
-        dev.do_FLR()
+        dev.do_FLR(is_hvm)
 
 class XendDomainInfo:
     """An object represents a domain.
@@ -693,19 +693,14 @@ class XendDomainInfo:
 
         # Test whether the device is owned by pciback. For instance, we can't
         # hotplug a device being used by Dom0 itself to an HVM guest.
-        from xen.xend.server.pciif import PciDevice, parse_pci_name
         try:
             pci_device = PciDevice(new_dev)
         except Exception, e:
             raise VmError("pci: failed to locate device and "+
-                    "parse it's resources - "+str(e))
+                    "parse its resources - "+str(e))
         if pci_device.driver!='pciback' and pci_device.driver!='pci-stub':
-            raise VmError(("pci: PCI Backend does not own device "+ \
-                    "%s\n"+ \
-                    "See the pciback.hide kernel "+ \
-                    "command-line parameter or\n"+ \
-                    "bind your slot/device to the PCI backend using sysfs" \
-                    )%(pci_device.name))
+            raise VmError(("pci: PCI Backend and pci-stub don't own device 
%s")\
+                            %pci_device.name)
 
         # Check non-page-aligned MMIO BAR.
         if pci_device.has_non_page_aligned_bar and arch.type != "ia64":
@@ -1148,7 +1143,7 @@ class XendDomainInfo:
             pci_device = PciDevice(pci_dev)
         except Exception, e:
             raise VmError("pci: failed to locate device and "+
-                    "parse it's resources - "+str(e))
+                    "parse its resources - "+str(e))
         coassignment_list = pci_device.find_coassigned_devices()
         coassignment_list.remove(pci_device.name)
         assigned_pci_device_str_list = self._get_assigned_pci_devices()
@@ -2458,6 +2453,22 @@ class XendDomainInfo:
             pci = map(lambda x: x[0:4], pci)  # strip options 
             pci_str = str(pci)
 
+        # This test is done for both pv and hvm guest.
+        for p in pci:
+            pci_name = '%04x:%02x:%02x.%x' % \
+                (parse_hex(p[0]), parse_hex(p[1]), parse_hex(p[2]), 
parse_hex(p[3]))
+            try:
+                pci_device = PciDevice(parse_pci_name(pci_name))
+            except Exception, e:
+                raise VmError("pci: failed to locate device and "+
+                    "parse its resources - "+str(e))
+            if pci_device.driver!='pciback' and pci_device.driver!='pci-stub':
+                raise VmError(("pci: PCI Backend and pci-stub don't own device 
%s")\
+                                %pci_device.name)
+            if pci_name in get_all_assigned_pci_devices():
+                raise VmError("failed to assign device %s that has"
+                              " already been assigned to other domain." % 
pci_name)
+
         if hvm and pci_str != '':
             bdf = xc.test_assign_device(0, pci_str)
             if bdf != 0:
@@ -2469,17 +2480,9 @@ class XendDomainInfo:
                 devfn = (bdf >> 8) & 0xff
                 dev = (devfn >> 3) & 0x1f
                 func = devfn & 0x7
-                raise VmError("failed to assign device(%x:%x.%x): maybe it has"
+                raise VmError("failed to assign device %02x:%02x.%x: maybe it 
has"
                               " already been assigned to other domain, or 
maybe"
                               " it doesn't exist." % (bus, dev, func))
-
-        # This test is done for both pv and hvm guest.
-        for p in pci:
-            pci_name = '%04x:%02x:%02x.%x' % \
-                (parse_hex(p[0]), parse_hex(p[1]), parse_hex(p[2]), 
parse_hex(p[3]))
-            if pci_name in get_all_assigned_pci_devices():
-                raise VmError("failed to assign device %s that has"
-                              " already been assigned to other domain." % 
pci_name)
 
         # register the domain in the list 
         from xen.xend import XendDomain
@@ -2810,7 +2813,7 @@ class XendDomainInfo:
             try:
                 xc.domain_destroy_hook(self.domid)
                 xc.domain_pause(self.domid)
-                do_FLR(self.domid)
+                do_FLR(self.domid, self.info.is_hvm())
                 xc.domain_destroy(self.domid)
                 for state in DOM_STATES_OLD:
                     self.info[state] = 0
diff -r edf21ab7d7a4 -r 9a5e12b150b5 tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py     Sun Aug 02 12:26:23 2009 +0100
+++ b/tools/python/xen/xend/server/pciif.py     Sun Aug 02 12:27:51 2009 +0100
@@ -279,7 +279,7 @@ class PciController(DevController):
             dev = PciDevice(pci_dev)
         except Exception, e:
             raise VmError("pci: failed to locate device and "+
-                    "parse it's resources - "+str(e))
+                    "parse its resources - "+str(e))
 
         if dev.driver!='pciback' and dev.driver!='pci-stub':
             raise VmError(("pci: PCI Backend and pci-stub don't own "+ \
@@ -373,7 +373,7 @@ class PciController(DevController):
                 dev = PciDevice(pci_dev)
             except Exception, e:
                 raise VmError("pci: failed to locate device and "+
-                        "parse it's resources - "+str(e))
+                        "parse its resources - "+str(e))
             if (dev.dev_type == DEV_TYPE_PCIe_ENDPOINT) and not dev.pcie_flr:
                 if dev.bus == 0:
                     # We cope with this case by using the Dstate transition
@@ -383,6 +383,9 @@ class PciController(DevController):
                         ' method or some vendor specific methods if available.'
                     log.warn(err_msg % dev.name)
                 else:
+                    if not self.vm.info.is_hvm():
+                        continue
+
                     funcs = dev.find_all_the_multi_functions()
                     dev.devs_check_driver(funcs)
                     for f in funcs:
@@ -403,6 +406,9 @@ class PciController(DevController):
                             ' specific methods if available.'
                         log.warn(err_msg % dev.name)
                 else:
+                    if not self.vm.info.is_hvm():
+                        continue
+
                     # All devices behind the uppermost PCI/PCI-X bridge must 
be\
                     # co-assigned to the same guest.
                     devs_str = dev.find_coassigned_pci_devices(True)
@@ -455,7 +461,7 @@ class PciController(DevController):
             dev = PciDevice(pci_dev)
         except Exception, e:
             raise VmError("pci: failed to locate device and "+
-                    "parse it's resources - "+str(e))
+                    "parse its resources - "+str(e))
 
         if dev.driver!='pciback' and dev.driver!='pci-stub':
             raise VmError(("pci: PCI Backend and pci-stub don't own device "+ \
@@ -463,7 +469,7 @@ class PciController(DevController):
 
         # Need to do FLR here before deassign device in order to terminate
         # DMA transaction, etc
-        dev.do_FLR()
+        dev.do_FLR(self.vm.info.is_hvm())
 
         bdf = xc.deassign_device(fe_domid, pci_dict_to_xc_str(pci_dev))
         pci_str = pci_dict_to_bdf_str(pci_dev)
diff -r edf21ab7d7a4 -r 9a5e12b150b5 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Sun Aug 02 12:26:23 2009 +0100
+++ b/tools/python/xen/xm/main.py       Sun Aug 02 12:27:51 2009 +0100
@@ -2538,6 +2538,10 @@ def xm_pci_attach(args):
 
     (dom, dev) = parse_pci_configuration(params, config_pci_opts)
 
+    attached = attached_pci_dict(dom)
+
+    attached_dev = map(lambda x: find_attached(attached, x, False), dev)
+
     head_dev = dev.pop(0)
     xm_pci_attach_one(dom, head_dev)
 
@@ -2724,19 +2728,24 @@ def xm_network_detach(args):
         arg_check(args, 'network-detach', 2, 3)
         detach(args, 'vif')
 
-def find_attached(attached, key):
+def find_attached(attached, key, detaching):
     l = filter(lambda dev: pci_dict_cmp(dev, key), attached)
 
-    if len(l) == 0:
-         raise OptionError("pci: device is not attached: " +
-                           pci_dict_to_bdf_str(key))
-
-    # There shouldn't ever be more than one match,
-    # but perhaps an exception should be thrown if there is
-    return l[0]
+    if detaching:
+        if  len(l) == 0:
+             raise OptionError("pci: device %s is not attached!" %\
+                               pci_dict_to_bdf_str(key))
+        # There shouldn't ever be more than one match,
+        # but perhaps an exception should be thrown if there is
+        return l[0]
+    else:
+        if len(l) == 1:
+            raise  OptionError("pci: device %s has been attached! " %\
+                               pci_dict_to_bdf_str(key))
+        return None
 
 def find_attached_devfn(attached, key):
-    pci_dev = find_attached(attached, key)
+    pci_dev = find_attached(attached, key, True)
     return pci_dev['vdevfn']
 
 def xm_pci_detach(args):
@@ -2745,7 +2754,7 @@ def xm_pci_detach(args):
     (dom, dev) = parse_pci_configuration(args)
     attached = attached_pci_dict(dom)
 
-    attached_dev = map(lambda x: find_attached(attached, x), dev)
+    attached_dev = map(lambda x: find_attached(attached, x, True), dev)
 
     def f(pci_dev):
         vdevfn = int(pci_dev['vdevfn'], 16)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] xend: passthrough: loosen the pci co-assignment for pv guest, Xen patchbot-unstable <=