aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2013-06-10 16:48:09 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2013-06-14 12:28:59 -0400
commit098b1aeaf4d6149953b8f1f8d55c21d85536fbff (patch)
tree984d5ae7f55ea1a01e650c6b9c6111a38691d0e4
parent09e99da766a6a701eb4d72004872d1144291d53b (diff)
xen/pcifront: Deal with toolstack missing 'XenbusStateClosing' state.
There are two tool-stack that can instruct the Xen PCI frontend and backend to change states: 'xm' (Python code with a daemon), and 'xl' (C library - does not keep state changes). With the 'xm', the path to disconnect a single PCI device (xm pci-detach <guest> <BDF>) is: 4(Connected)->7(Reconfiguring*)-> 8(Reconfigured)-> 4(Connected)->5(Closing*). The * is for states that the tool-stack sets. For 'xl', it is similar: 4(Connected)->7(Reconfiguring*)-> 8(Reconfigured)-> 4(Connected) Both of them also tear down the XenBus structure, so the backend state ends up going in the 3(Initialised) and calls pcifront_xenbus_remove. When a PCI device is plugged back in (xm pci-attach <guest> <BDF>) both of them follow the same pattern: 2(InitWait*), 3(Initialized*), 4(Connected*)->4(Connected). [xen-pcifront ignores the 2,3 state changes and only acts when 4 (Connected) has been reached] Note that this is for a _single_ PCI device. If there were two PCI devices and only one was disconnected 'xm' would show the same state changes. The problem is that git commit 3d925320e9e2de162bd138bf97816bda8c3f71be ("xen/pcifront: Use Xen-SWIOTLB when initting if required") introduced a mechanism to initialize the SWIOTLB when the Xen PCI front moves to Connected state. It also had some aggressive seatbelt code check that would warn the user if one tried to change to Connected state without hitting first the Closing state: pcifront pci-0: PCI frontend already installed! However, that code can be relaxed and we can continue on working even if the frontend is instructed to be the 'Connected' state with no devices and then gets tickled to be in 'Connected' state again. In other words, this 4(Connected)->5(Closing)->4(Connected) state was expected, while 4(Connected)->.... anything but 5(Closing)->4(Connected) was not. This patch removes that aggressive check and allows Xen pcifront to work with the 'xl' toolstack (for one or more PCI devices) and with 'xm' toolstack (for more than two PCI devices). Acked-by: Bjorn Helgaas <bhelgaas@google.com> Cc: linux-pci@vger.kernel.org Cc: stable@vger.kernel.org [v2: Added in the description about two PCI devices] Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-rw-r--r--drivers/pci/xen-pcifront.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index 966abc6054d7..f7197a790341 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -678,10 +678,9 @@ static int pcifront_connect_and_init_dma(struct pcifront_device *pdev)
678 if (!pcifront_dev) { 678 if (!pcifront_dev) {
679 dev_info(&pdev->xdev->dev, "Installing PCI frontend\n"); 679 dev_info(&pdev->xdev->dev, "Installing PCI frontend\n");
680 pcifront_dev = pdev; 680 pcifront_dev = pdev;
681 } else { 681 } else
682 dev_err(&pdev->xdev->dev, "PCI frontend already installed!\n");
683 err = -EEXIST; 682 err = -EEXIST;
684 } 683
685 spin_unlock(&pcifront_dev_lock); 684 spin_unlock(&pcifront_dev_lock);
686 685
687 if (!err && !swiotlb_nr_tbl()) { 686 if (!err && !swiotlb_nr_tbl()) {
@@ -848,7 +847,7 @@ static int pcifront_try_connect(struct pcifront_device *pdev)
848 goto out; 847 goto out;
849 848
850 err = pcifront_connect_and_init_dma(pdev); 849 err = pcifront_connect_and_init_dma(pdev);
851 if (err) { 850 if (err && err != -EEXIST) {
852 xenbus_dev_fatal(pdev->xdev, err, 851 xenbus_dev_fatal(pdev->xdev, err,
853 "Error setting up PCI Frontend"); 852 "Error setting up PCI Frontend");
854 goto out; 853 goto out;