From: Yinghai Lu <yinghai@kernel.org>
To: Bjorn Helgaas <bhelgaas@google.com>
Cc: linux-pci@vger.kernel.org, Yinghai Lu <yinghai@kernel.org>,
Yijing Wang <wangyijing@huawei.com>, Jiang Liu <liuj97@gmail.com>
Subject: [PATCH] PCI: Separate stop and remove devices in pciehp
Date: Fri, 19 Jul 2013 12:14:17 -0700 [thread overview]
Message-ID: <1374261258-23036-2-git-send-email-yinghai@kernel.org> (raw)
In-Reply-To: <1374261258-23036-1-git-send-email-yinghai@kernel.org>
After commit dc087f2f6a2925e81831f3016b9cbb6e470e7423
(PCI: Simplify IOV implementation and fix reference count races)
VF need to be removed via virtfn_remove to make sure ref to PF
is put back.
So we can not call stop_and_remove for VF before PF, that will
make VF get removed directly before PF's driver try to use
virtfn_remove to do it.
Solution is separating stop and remove in two iterations.
In first iteration, we stop VF driver at first with iterating devices
reversely, and later during stop PF driver, disable_sriov will use
virtfn_remove to remove VFs.
Also some driver (like mlx4_core) need VF's driver get stopped before PF.
To make it simple, separate VGA checking out and do that at first,
if there is VGA in the chain, do even try to stop or remove any device
under that bus.
Need this one for v3.11.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Yijing Wang <wangyijing@huawei.com>
Cc: Jiang Liu <liuj97@gmail.com>
---
drivers/pci/hotplug/pciehp_pci.c | 46 ++++++++++++++++++++++++++-------------
drivers/pci/remove.c | 6 +++--
include/linux/pci.h | 2 +
3 files changed, 37 insertions(+), 17 deletions(-)
Index: linux-2.6/drivers/pci/hotplug/pciehp_pci.c
===================================================================
--- linux-2.6.orig/drivers/pci/hotplug/pciehp_pci.c
+++ linux-2.6/drivers/pci/hotplug/pciehp_pci.c
@@ -92,26 +92,37 @@ int pciehp_unconfigure_device(struct slo
if (ret)
presence = 0;
+ /* check if VGA is around */
+ if (presence) {
+ list_for_each_entry(dev, &parent->devices, bus_list) {
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+ pci_read_config_byte(dev, PCI_BRIDGE_CONTROL,
+ &bctl);
+ if (bctl & PCI_BRIDGE_CTL_VGA) {
+ ctrl_err(ctrl,
+ "Cannot remove display device %s\n",
+ pci_name(dev));
+ return -EINVAL;
+ }
+ }
+ }
+ }
+
/*
- * Need to iterate device reversely, as during
+ * Now VF need to be removed via virtfn_remove to make
+ * sure ref to PF is put back. Some driver (mlx4_core) need
+ * VF's driver get stopped before PF.
+ * So we need to stop VF driver at first, that means
+ * loop reversely, and later during stop PF driver,
+ * disable_sriov will use virtfn_remove to remove VFs.
+ * Also we can not loop without reverse, as during
* stop PF driver, VF will be removed, the list_for_each
* could point to removed VF with temp.
*/
list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
- bus_list) {
- pci_dev_get(dev);
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
- pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
- if (bctl & PCI_BRIDGE_CTL_VGA) {
- ctrl_err(ctrl,
- "Cannot remove display device %s\n",
- pci_name(dev));
- pci_dev_put(dev);
- rc = -EINVAL;
- break;
- }
- }
- pci_stop_and_remove_bus_device(dev);
+ bus_list) {
+ pci_stop_bus_device(dev);
+
/*
* Ensure that no new Requests will be generated from
* the device.
@@ -122,6 +133,11 @@ int pciehp_unconfigure_device(struct slo
command |= PCI_COMMAND_INTX_DISABLE;
pci_write_config_word(dev, PCI_COMMAND, command);
}
+ }
+
+ list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) {
+ pci_dev_get(dev);
+ pci_remove_bus_device(dev);
pci_dev_put(dev);
}
Index: linux-2.6/drivers/pci/remove.c
===================================================================
--- linux-2.6.orig/drivers/pci/remove.c
+++ linux-2.6/drivers/pci/remove.c
@@ -56,7 +56,7 @@ void pci_remove_bus(struct pci_bus *bus)
}
EXPORT_SYMBOL(pci_remove_bus);
-static void pci_stop_bus_device(struct pci_dev *dev)
+void pci_stop_bus_device(struct pci_dev *dev)
{
struct pci_bus *bus = dev->subordinate;
struct pci_dev *child, *tmp;
@@ -75,8 +75,9 @@ static void pci_stop_bus_device(struct p
pci_stop_dev(dev);
}
+EXPORT_SYMBOL(pci_stop_bus_device);
-static void pci_remove_bus_device(struct pci_dev *dev)
+void pci_remove_bus_device(struct pci_dev *dev)
{
struct pci_bus *bus = dev->subordinate;
struct pci_dev *child, *tmp;
@@ -92,6 +93,7 @@ static void pci_remove_bus_device(struct
pci_destroy_dev(dev);
}
+EXPORT_SYMBOL(pci_remove_bus_device);
/**
* pci_stop_and_remove_bus_device - remove a PCI device and any children
Index: linux-2.6/include/linux/pci.h
===================================================================
--- linux-2.6.orig/include/linux/pci.h
+++ linux-2.6/include/linux/pci.h
@@ -754,6 +754,8 @@ u8 pci_common_swizzle(struct pci_dev *de
struct pci_dev *pci_dev_get(struct pci_dev *dev);
void pci_dev_put(struct pci_dev *dev);
void pci_remove_bus(struct pci_bus *b);
+void pci_stop_bus_device(struct pci_dev *dev);
+void pci_remove_bus_device(struct pci_dev *dev);
void pci_stop_and_remove_bus_device(struct pci_dev *dev);
void pci_stop_root_bus(struct pci_bus *bus);
void pci_remove_root_bus(struct pci_bus *bus);
next prev parent reply other threads:[~2013-07-19 19:14 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-19 19:14 [PATCH] PCI: Fix hotplug remove with sriov again Yinghai Lu
2013-07-19 19:14 ` Yinghai Lu [this message]
2013-07-22 21:23 ` [PATCH] PCI: Separate stop and remove devices in pciehp Bjorn Helgaas
2013-07-23 2:32 ` Yinghai Lu
2013-07-23 15:56 ` Bjorn Helgaas
2013-07-23 22:44 ` Yinghai Lu
2013-07-23 23:15 ` Yinghai Lu
2013-07-24 4:00 ` Yijing Wang
2013-07-26 22:05 ` Bjorn Helgaas
2013-07-27 14:30 ` Yinghai Lu
2013-07-19 19:14 ` [PATCH] PCI: Stop sriov before remove PF Yinghai Lu
2013-07-19 21:46 ` Alexander Duyck
2013-07-19 22:44 ` Yinghai Lu
2013-07-19 23:22 ` Alexander Duyck
2013-07-23 15:34 ` Don Dutile
2013-07-23 16:10 ` Yinghai Lu
2013-07-22 23:15 ` Bjorn Helgaas
2013-07-23 1:59 ` Yinghai Lu
2013-07-22 7:07 ` [PATCH] PCI: Fix hotplug remove with sriov again Yijing Wang
2013-07-22 17:39 ` Bjorn Helgaas
2013-07-22 17:48 ` Yinghai Lu
2013-07-23 17:40 ` Bjorn Helgaas
2013-07-24 2:01 ` Yijing Wang
2013-07-24 2:04 ` Yinghai Lu
2013-07-24 2:15 ` Yinghai Lu
2013-07-24 2:25 ` Yijing Wang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1374261258-23036-2-git-send-email-yinghai@kernel.org \
--to=yinghai@kernel.org \
--cc=bhelgaas@google.com \
--cc=linux-pci@vger.kernel.org \
--cc=liuj97@gmail.com \
--cc=wangyijing@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).