PCI core learns hotplug
Subsystems (2)
v4 cover PCI core learns hotplug
We're getting close to the new merge window, and I _think_ this patch series is ready for consideration. Notably:
- multiple rescans/removes of devices with and without bridges
- verified that resource allocation after multiple remove/rescan cycles is the same as what we had during initial boot
- fixes the complete suckage of fakephp (that I created)
- doesn't affect existing hotplug drivers
- tested on x86 and ia64 platforms
Please review, and consider testing. For testing ease, you can pull from my git branch:
git://git.kernel.org/pub/scm/linux/kernel/git/achiang/pci-hotplug.git branch 'test-20090318' is what you want
Note, this test branch does contain the small assorted patches in AER and the PCIe portdriver that I fixed along the way, but does not contain the sysfs callback mutex that I introduced to protect myself from Vegard Nossum. ;) If you want to hammer away at the sysfs interface, please apply this patch on top:
http://thread.gmane.org/gmane.linux.kernel/806648
What I'm continuing to do:
- investigate converting existing hotplug drivers to use new pci_rescan_bus() interface
Thanks.
/ac
v3 -> v4:
- protect sysfs interfaces with mutex
- undo changes in pci_do_scan_bus
- introduce pci_rescan_bus instead
- do not initialize bridges more than once
v2 -> v3:
- properly remove device with internal bridge
- added Kenji Kaneshige's pci_is_root_bus() interface
- dropped whitespace cleanups for another time
v1 -> v2:
- incorporated lots of Trent Piepho's work
- beefed up pci_do_scan_bus as heavy lifter for rescanning
- small bugfixes folded into earlier patches to get everything working
---
Alex Chiang (8):
PCI Hotplug: schedule fakephp for feature removal PCI Hotplug: rename legacy_fakephp to fakephp
PCI: Introduce /sys/bus/pci/devices/.../rescan
PCI: Introduce /sys/bus/pci/devices/.../remove
PCI: Introduce /sys/bus/pci/rescan
PCI: Introduce pci_rescan_bus()
PCI: do not initialize bridges more than once
PCI: always scan child buses
Kenji Kaneshige (1):
PCI: pci_is_root_bus helper
Trent Piepho (3):
PCI Hotplug: restore fakephp interface with complete reimplementation
PCI: pci_scan_slot() returns newly found devices
PCI: don't scan existing devices
Documentation/ABI/testing/sysfs-bus-pci | 27 ++ Documentation/feature-removal-schedule.txt | 32 ++ Documentation/filesystems/sysfs-pci.txt | 10 + drivers/pci/hotplug/fakephp.c | 443 +++++++--------------------- drivers/pci/pci-driver.c | 1 drivers/pci/pci-sysfs.c | 95 ++++++ drivers/pci/pci.h | 6 drivers/pci/probe.c | 103 ++++--- drivers/pci/setup-bus.c | 3 include/linux/pci.h | 12 + 10 files changed, 358 insertions(+), 374 deletions(-)
PATCH v4 1/12 PCI: pci_is_root_bus helper
From: Kenji Kaneshige <[email protected]>
Introduce pci_is_root_bus helper function. This will help make code more consistent, as well as prevent incorrect assumptions (such as pci_bus->self == NULL on a root bus, which is not always true).
---
include/linux/pci.h | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-)
include/linux/pci.h +9 -0
@@ -341,6 +341,15 @@ struct pci_bus {#define pci_bus_b (n) list_entry(n, struct pci_bus, node)#define to_pci_bus (n) container_of(n, struct pci_bus, dev) +/* +* Returns true if the pci bus is root (behind host-pci bridge), +* false otherwise +*/ +static inline bool pci_is_root_bus (struct pci_bus *pbus) +{ +return !(pbus->parent); +} +#ifdef CONFIG_PCI_MSI static inline bool pci_dev_msi_enabled (struct pci_dev *pci_dev) {
PATCH v4 2/12 PCI: don't scan existing devices
In reply to Alex ChiangFrom: Trent Piepho <[email protected]>
pci_scan_single_device is supposed to add newly discovered devices to pci_bus->devices, but doesn't check to see if the device has already been added. This can cause problems if we ever want to use this interface to rescan the PCI bus.
If the device is already added, just return it.
---
drivers/pci/probe.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)
drivers/pci/probe.c +6 -0
@@ -1006,6 +1006,12 @@ struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn) {struct pci_dev *dev; + dev =pci_get_slot (bus, devfn); +if (dev) { +pci_dev_put (dev); +return dev; + } + dev =pci_scan_device (bus, devfn);if (!dev)return NULL ;
PATCH v4 3/12 PCI: pci_scan_slot() returns newly found devices
In reply to Alex ChiangFrom: Trent Piepho <[email protected]>
pci_scan_slot() has been rewritten to be less complex and will now return the number of *new* devices found.
Existing callers need not worry because they already assume that they can't call pci_scan_slot() on an already-scanned slot.
Thus, there is no semantic change for existing callers: returning newly found devices (this patch) is exactly equal to returning all found devices (before this patch).
This patch adds some more groundwork to allow us to rescan the PCI bus during runtime to discover newly added devices.
---
drivers/pci/probe.c | 35 +++++++++++++---------------------- 1 files changed, 13 insertions(+), 22 deletions(-)
drivers/pci/probe.c +13 -22
@@ -1030,35 +1030,26 @@ EXPORT_SYMBOL(pci_scan_single_device);* Scan a PCI slot on the specified PCI bus for devices, adding * discovered devices to the @bus->devices list. New devices * will not have is_added set. +* +* Returns the number of new devices found. */ int pci_scan_slot (struct pci_bus *bus,int devfn) { -int func, nr =0 ; -int scan_all_fns; - - scan_all_fns =pcibios_scan_all_fns (bus, devfn); - -for (func =0 ; func <8 ; func++, devfn++) { -struct pci_dev *dev; +int fn, nr =0 ; +struct pci_dev *dev; - dev =pci_scan_single_device (bus, devfn); -if (dev) { +if ((dev =pci_scan_single_device (bus, devfn))) +if (!dev->is_added)/* new device? */ nr++; -/* -* If this is a single function device, -* don't scan past the first function. -*/ -if (!dev->multifunction) { -if (func >0 ) { - dev->multifunction =1 ; - }else { -break ; - } +if ((dev && dev->multifunction) || + (!dev &&pcibios_scan_all_fns (bus, devfn))) { +for (fn =1 ; fn <8 ; fn++) { +if ((dev =pci_scan_single_device (bus, devfn + fn))) { +if (!dev->is_added) + nr++; + dev->multifunction =1 ; } - }else { -if (func ==0 && !scan_all_fns) -break ; } }
PATCH v4 4/12 PCI: always scan child buses
In reply to Alex ChiangWhile scanning bridges, we stop our scan if we encounter a bus that we've seen before, to work around some buggy chipsets. This is a good idea, but prevents us from fully scanning the PCI bus at a future time (to find newly hot-added devices, for example).
Change the logic so that we skip _re-adding_ an existing bus that we've seen before, but also allow the scan to descend to all child buses.
Now that we're potentially scanning our child buses again, we also need to be sure not to attempt re-initializing their BARs so we avoid that.
This patch lays the groundwork to allow the user to issue a rescan of the PCI bus at any time.
---
drivers/pci/probe.c | 33 +++++++++++++++++++-------------- 1 files changed, 19 insertions(+), 14 deletions(-)
drivers/pci/probe.c +19 -14
@@ -511,21 +511,21 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,/* * If we already got to this bus through a different bridge, -* ignore it. This can happen with the i450NX chipset. +* don't re-add it. This can happen with the i450NX chipset. +* +* However, we continue to descend down the hierarchy and +* scan remaining child buses. */ -if (pci_find_bus (pci_domain_nr (bus), busnr)) { -dev_info (&dev->dev,"bus %04x:%02x already known\n" , -pci_domain_nr (bus), busnr); - goto out; + child =pci_find_bus (pci_domain_nr (bus), busnr); +if (!child) { + child =pci_add_new_bus (bus, dev, busnr); +if (!child) + goto out; + child->primary = buses &0xFF ; + child->subordinate = (buses >>16 ) &0xFF ; + child->bridge_ctl = bctl; } - child =pci_add_new_bus (bus, dev, busnr); -if (!child) - goto out; - child->primary = buses &0xFF ; - child->subordinate = (buses >>16 ) &0xFF ; - child->bridge_ctl = bctl; - cmax =pci_scan_child_bus (child);if (cmax > max) max = cmax;
@@ -1075,8 +1075,13 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)* After performing arch-dependent fixup of the bus, look behind * all PCI-to-PCI bridges on this bus. */ -pr_debug ("PCI: Fixups for bus %04x:%02x\n" ,pci_domain_nr (bus), bus->number); -pcibios_fixup_bus (bus); +if (!bus->is_added) { +pr_debug ("PCI: Fixups for bus %04x:%02x\n" ,pci_domain_nr (bus), bus->number); +pcibios_fixup_bus (bus); +if (pci_is_root_bus (bus)) + bus->is_added =1 ; + } +for (pass=0 ; pass <2 ; pass++)list_for_each_entry (dev, &bus->devices, bus_list) { if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
PATCH v4 5/12 PCI: do not initialize bridges more than once
In reply to Alex ChiangIn preparation for PCI core hotplug, we need to ensure that we do not attempt to re-initialize bridges that have already been initialized.
We only need to worry about non-root buses, since we will not allow root bus removal.
---
drivers/pci/setup-bus.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
drivers/pci/setup-bus.c +3 -0
@@ -144,6 +144,9 @@ static void pci_setup_bridge(struct pci_bus *bus)struct pci_bus_region region;u32 l, bu, lu, io_upper16; +if (!pci_is_root_bus (bus) && bus->is_added) +return ; +dev_info (&bridge->dev,"PCI bridge, secondary bus %04x:%02x\n" ,pci_domain_nr (bus), bus->number);
PATCH v4 6/12 PCI: Introduce pci_rescan_bus()
In reply to Alex ChiangThis API is used by the PCI core to rescan a bus and rediscover newly added devices.
Over time, it is expected that the various PCI hotplug drivers will migrate to this interface and away from the old pci_do_scan_bus() interface.
---
drivers/pci/hotplug/fakephp.c | 6 +++--- drivers/pci/probe.c | 29 +++++++++++++++++++++++++++++ include/linux/pci.h | 3 +++ 3 files changed, 35 insertions(+), 3 deletions(-)
drivers/pci/hotplug/fakephp.c +3 -3
@@ -245,12 +245,12 @@ static int pci_rescan_slot(struct pci_dev *temp)/** -* pci_rescan_bus - Rescan PCI bus +* pci_rescan_bus_local - fakephp version of rescan PCI bus * @bus: the PCI bus to rescan * * Call pci_rescan_slot for each possible function of the bus. */ -static void pci_rescan_bus (const struct pci_bus *bus) +static void pci_rescan_bus_local (const struct pci_bus *bus) {unsigned int devfn;struct pci_dev *dev;
@@ -291,7 +291,7 @@ static void pci_rescan_buses(const struct list_head *list)const struct list_head *l;list_for_each (l,list) {const struct pci_bus *b =pci_bus_b (l); -pci_rescan_bus (b); +pci_rescan_bus_local (b);pci_rescan_buses (&b->children); } }
drivers/pci/probe.c +29 -0
@@ -1195,10 +1195,39 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,EXPORT_SYMBOL (pci_scan_bus_parented);#ifdef CONFIG_HOTPLUG +/** +* pci_rescan_bus - scan a PCI bus for devices. +* @bus: PCI bus to scan +* +* Scan a PCI bus and child buses for new devices, adds them, +* and enables them. +* +* Returns the max number of subordinate bus discovered. +*/ +unsigned int __devinit pci_rescan_bus (struct pci_bus *bus) +{ +unsigned int max; +struct pci_dev *dev; + + max =pci_scan_child_bus (bus); +list_for_each_entry (dev, &bus->devices, bus_list) +if (dev->hdr_type ==PCI_HEADER_TYPE_BRIDGE || + dev->hdr_type ==PCI_HEADER_TYPE_CARDBUS ) +if (dev->subordinate) +pci_bus_size_bridges (dev->subordinate); + +pci_bus_assign_resources (bus); +pci_enable_bridges (bus); +pci_bus_add_devices (bus); + +return max; +} +EXPORT_SYMBOL (pci_add_new_bus);EXPORT_SYMBOL (pci_scan_slot);EXPORT_SYMBOL (pci_scan_bridge);EXPORT_SYMBOL_GPL (pci_scan_child_bus); +EXPORT_SYMBOL_GPL (pci_rescan_bus);#endif static int __init pci_sort_bf_cmp (const struct device *d_a,const struct device *d_b)
include/linux/pci.h +3 -0
@@ -710,6 +710,9 @@ int pci_back_from_sleep(struct pci_dev *dev);/* Functions for PCI Hotplug drivers to use */ int pci_bus_find_capability (struct pci_bus *bus,unsigned int devfn,int cap); +#ifdef CONFIG_HOTPLUG +unsigned int pci_rescan_bus (struct pci_bus *bus); +#endif /* Vital product data routines */ ssize_t pci_read_vpd (struct pci_dev *dev,loff_t pos,size_t count,void *buf);
Re: [PATCH v4 06/12] PCI: Introduce pci_rescan_bus()
Quoted 36 lines · On Wed, 18 Mar 2009 16:39:56 -0600 Alex Chiang <[email protected]> wrote:
This API is used by the PCI core to rescan a bus and rediscover newly added devices.
Over time, it is expected that the various PCI hotplug drivers will migrate to this interface and away from the old
pci_do_scan_bus()interface....
drivers/pci/probe.c +23
-0@@ -1195,10 +1195,39 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,EXPORT_SYMBOL (pci_scan_bus_parented);#ifdef CONFIG_HOTPLUG +/** +* pci_rescan_bus - scan a PCI bus for devices. +* @bus: PCI bus to scan +* +* Scan a PCI bus and child buses for new devices, adds them, +* and enables them. +* +* Returns the max number of subordinate bus discovered. +*/ +unsigned int __devinit pci_rescan_bus (struct pci_bus *bus) +{ +unsigned int max; +struct pci_dev *dev; + + max =pci_scan_child_bus (bus); +list_for_each_entry (dev, &bus->devices, bus_list) +if (dev->hdr_type ==PCI_HEADER_TYPE_BRIDGE || + dev->hdr_type ==PCI_HEADER_TYPE_CARDBUS ) +if (dev->subordinate) +pci_bus_size_bridges (dev->subordinate); + +pci_bus_assign_resources (bus); +pci_enable_bridges (bus);
drivers/pci/probe.c struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, · line 1230
Quoted 10 lines
drivers/pci/probe.c +6
-0+pci_bus_add_devices (bus); + +return max; +} +EXPORT_SYMBOL (pci_add_new_bus);EXPORT_SYMBOL (pci_scan_slot);EXPORT_SYMBOL (pci_scan_bridge);EXPORT_SYMBOL_GPL (pci_scan_child_bus); +EXPORT_SYMBOL_GPL (pci_rescan_bus);
uhm, is there any rationale for the seemingly-random mixup of export types in this interface?
Re: [PATCH v4 06/12] PCI: Introduce pci_rescan_bus()
* Andrew Morton <[email protected]>:
Quoted 43 lines · On Wed, 18 Mar 2009 16:39:56 -0600 Alex Chiang <[email protected]> wrote:
Quoted 42 lines
This API is used by the PCI core to rescan a bus and rediscover newly added devices.
Over time, it is expected that the various PCI hotplug drivers will migrate to this interface and away from the old
pci_do_scan_bus()interface....
drivers/pci/probe.c +28
-0@@ -1195,10 +1195,39 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,EXPORT_SYMBOL (pci_scan_bus_parented);#ifdef CONFIG_HOTPLUG +/** +* pci_rescan_bus - scan a PCI bus for devices. +* @bus: PCI bus to scan +* +* Scan a PCI bus and child buses for new devices, adds them, +* and enables them. +* +* Returns the max number of subordinate bus discovered. +*/ +unsigned int __devinit pci_rescan_bus (struct pci_bus *bus) +{ +unsigned int max; +struct pci_dev *dev; + + max =pci_scan_child_bus (bus); +list_for_each_entry (dev, &bus->devices, bus_list) +if (dev->hdr_type ==PCI_HEADER_TYPE_BRIDGE || + dev->hdr_type ==PCI_HEADER_TYPE_CARDBUS ) +if (dev->subordinate) +pci_bus_size_bridges (dev->subordinate); + +pci_bus_assign_resources (bus); +pci_enable_bridges (bus); +pci_bus_add_devices (bus); + +return max; +} +
Quoted 8 lines
drivers/pci/probe.c struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, · line 1230
Quoted 5 lines
drivers/pci/probe.c +1
-0EXPORT_SYMBOL (pci_add_new_bus);EXPORT_SYMBOL (pci_scan_slot);EXPORT_SYMBOL (pci_scan_bridge);EXPORT_SYMBOL_GPL (pci_scan_child_bus); +EXPORT_SYMBOL_GPL (pci_rescan_bus);uhm, is there any rationale for the seemingly-random mixup of export types in this interface?
History?
I've no clue why we're mixing EXPORT_SYMBOL and EXPORT_SYMBOL_GPL.
git-blame says that the mishmash existed pre-git.
For my new interface, I thought that EXPORT_SYMBOL_GPL would be most appropriate, but maybe not?
What would you like me to do? Make them all the same?
Thanks.
/ac
Re: [PATCH v4 06/12] PCI: Introduce pci_rescan_bus()
Quoted 53 lines · Alex Chiang
* Andrew Morton <[email protected]>:
Quoted 43 lines · On Wed, 18 Mar 2009 16:39:56 -0600 Alex Chiang <[email protected]> wrote:
Quoted 42 lines
This API is used by the PCI core to rescan a bus and rediscover newly added devices.
Over time, it is expected that the various PCI hotplug drivers will migrate to this interface and away from the old
pci_do_scan_bus()interface....
drivers/pci/probe.c +28
-0@@ -1195,10 +1195,39 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,EXPORT_SYMBOL (pci_scan_bus_parented);#ifdef CONFIG_HOTPLUG +/** +* pci_rescan_bus - scan a PCI bus for devices. +* @bus: PCI bus to scan +* +* Scan a PCI bus and child buses for new devices, adds them, +* and enables them. +* +* Returns the max number of subordinate bus discovered. +*/ +unsigned int __devinit pci_rescan_bus (struct pci_bus *bus) +{ +unsigned int max; +struct pci_dev *dev; + + max =pci_scan_child_bus (bus); +list_for_each_entry (dev, &bus->devices, bus_list) +if (dev->hdr_type ==PCI_HEADER_TYPE_BRIDGE || + dev->hdr_type ==PCI_HEADER_TYPE_CARDBUS ) +if (dev->subordinate) +pci_bus_size_bridges (dev->subordinate); + +pci_bus_assign_resources (bus); +pci_enable_bridges (bus); +pci_bus_add_devices (bus); + +return max; +} +Quoted 8 lines
drivers/pci/probe.c struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, · line 1230
Quoted 5 lines
drivers/pci/probe.c +1
-0EXPORT_SYMBOL (pci_add_new_bus);EXPORT_SYMBOL (pci_scan_slot);EXPORT_SYMBOL (pci_scan_bridge);EXPORT_SYMBOL_GPL (pci_scan_child_bus); +EXPORT_SYMBOL_GPL (pci_rescan_bus);uhm, is there any rationale for the seemingly-random mixup of export types in this interface?
Quoted 3 lines
History?
I've no clue why we're mixing
EXPORT_SYMBOLandEXPORT_SYMBOL_GPL.
I do :)
New PCI core exports were added with _GPL, it's the older ones that were left at the "normal" level.
Quoted 4 lines
git-blame says that the mishmash existed pre-git.
For my new interface, I thought that
EXPORT_SYMBOL_GPLwould be most appropriate, but maybe not?
Yes it is, pci hotplug exports has always been EXPORT_SYMBOL_GPL(), in fact I think it was the first in-tree user of this marking.
Quoted 1 line
What would you like me to do? Make them all the same?
New ones should be _GPL() please.
But please put the export in the proper place, checkpatch.pl will complain if you do not. Which means you didn't run it on your patches :)
thanks,
greg k-h
Re: [PATCH v4 06/12] PCI: Introduce pci_rescan_bus()
* Greg KH <[email protected]>:
Quoted 30 lines · Alex Chiang
Quoted 9 lines
* Andrew Morton <[email protected]>:
Quoted 8 lines · On Wed, 18 Mar 2009 16:39:56 -0600 Alex Chiang <[email protected]> wrote:
Quoted 6 lines
EXPORT_SYMBOL(pci_add_new_bus);
EXPORT_SYMBOL(pci_scan_slot);
EXPORT_SYMBOL(pci_scan_bridge);
EXPORT_SYMBOL_GPL(pci_scan_child_bus);
+EXPORT_SYMBOL_GPL(pci_rescan_bus);Quoted 6 lines
Quoted 2 lines
uhm, is there any rationale for the seemingly-random mixup of export types in this interface?
History?
I've no clue why we're mixing
EXPORT_SYMBOLandEXPORT_SYMBOL_GPL.I do :)
New PCI core exports were added with
_GPL, it's the older ones that were left at the "normal" level.Quoted 4 lines
git-blame says that the mishmash existed pre-git.
For my new interface, I thought that
EXPORT_SYMBOL_GPLwould be most appropriate, but maybe not?Yes it is, pci hotplug exports has always been
EXPORT_SYMBOL_GPL(), in fact I think it was the first in-tree user of this marking.
Quoted 7 lines
Quoted 1 line
What would you like me to do? Make them all the same?
New ones should be
_GPL()please.But please put the export in the proper place, checkpatch.pl will complain if you do not. Which means you didn't run it on your patches :)
Andrew already yelled at me privately about checkpatch.
I went over and ran it on all my patches, and that was indeed one of the complaints.
But when it comes to file consistency vs "letter of the law" I like to keep things consistent (even if broken) in the file.
I could go back and move all those EXPORT_SYMBOL declarations to the "proper" place. Is that too much noise though?
Thanks.
/ac
Re: [PATCH v4 06/12] PCI: Introduce pci_rescan_bus()
Quoted 8 lines · Alex Chiang
I went over and ran it on all my patches, and that was indeed one of the complaints.
But when it comes to file consistency vs "letter of the law" I like to keep things consistent (even if broken) in the file.
I could go back and move all those
EXPORT_SYMBOLdeclarations to the "proper" place. Is that too much noise though?
The accepted way to do this is to add a prep patch which just fixes the checkpatch warnings (ie moves the EXPORT_SYMBOLs). Then your patch is all shiny and fresh.
Signature · 4 lines
Matthew Wilcox Intel Open Source Technology Centre "Bill, look, we understand that you're interested in selling us this operating system, but compare it to ours. We can't possibly take such a retrograde step."
Re: [PATCH v4 06/12] PCI: Introduce pci_rescan_bus()
In reply to Alex ChiangQuoted 41 lines · Alex Chiang
* Greg KH <[email protected]>:
Quoted 30 lines · Alex Chiang
Quoted 9 lines
* Andrew Morton <[email protected]>:
Quoted 8 lines · On Wed, 18 Mar 2009 16:39:56 -0600 Alex Chiang <[email protected]> wrote:
Quoted 6 lines
EXPORT_SYMBOL(pci_add_new_bus);
EXPORT_SYMBOL(pci_scan_slot);
EXPORT_SYMBOL(pci_scan_bridge);
EXPORT_SYMBOL_GPL(pci_scan_child_bus);
+EXPORT_SYMBOL_GPL(pci_rescan_bus);Quoted 6 lines
Quoted 2 lines
uhm, is there any rationale for the seemingly-random mixup of export types in this interface?
History?
I've no clue why we're mixing
EXPORT_SYMBOLandEXPORT_SYMBOL_GPL.I do :)
New PCI core exports were added with
_GPL, it's the older ones that were left at the "normal" level.Quoted 4 lines
git-blame says that the mishmash existed pre-git.
For my new interface, I thought that
EXPORT_SYMBOL_GPLwould be most appropriate, but maybe not?Yes it is, pci hotplug exports has always been
EXPORT_SYMBOL_GPL(), in fact I think it was the first in-tree user of this marking.Quoted 7 lines
Quoted 1 line
What would you like me to do? Make them all the same?
New ones should be
_GPL()please.But please put the export in the proper place, checkpatch.pl will complain if you do not. Which means you didn't run it on your patches :)
Andrew already yelled at me privately about checkpatch.
Quoted 8 lines
I went over and ran it on all my patches, and that was indeed one of the complaints.
But when it comes to file consistency vs "letter of the law" I like to keep things consistent (even if broken) in the file.
I could go back and move all those
EXPORT_SYMBOLdeclarations to the "proper" place. Is that too much noise though?
Too much noise for this patch, yes.
Put things in the right place for new patches/changes.
If you want to go back and just make a "fix this file to be checkpatch clean" patch, that's fine as well, but don't merge it with other changes at the same time, as that makes it pretty unreviewable.
Hope this helps,
greg k-h
Re: [PATCH v4 06/12] PCI: Introduce pci_rescan_bus()
In reply to Alex ChiangQuoted 17 lines · On Wed, 18 Mar 2009 16:39:56 -0600 Alex Chiang <[email protected]> wrote:
drivers/pci/probe.c +17
-0+/** +* pci_rescan_bus - scan a PCI bus for devices. +* @bus: PCI bus to scan +* +* Scan a PCI bus and child buses for new devices, adds them, +* and enables them. +* +* Returns the max number of subordinate bus discovered. +*/ +unsigned int __devinit pci_rescan_bus (struct pci_bus *bus) +{ +unsigned int max; +struct pci_dev *dev; + + max =pci_scan_child_bus (bus); +list_for_each_entry (dev, &bus->devices, bus_list) + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
drivers/pci/probe.c struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, · line 1224
Quoted 10 lines
drivers/pci/probe.c +10
-0+ dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) +if (dev->subordinate) +pci_bus_size_bridges (dev->subordinate); + +pci_bus_assign_resources (bus); +pci_enable_bridges (bus); +pci_bus_add_devices (bus); + +return max; +}
The conspicuous lack of locking for the list walk requires either
a) documenting or
b) fixing
IMO.
Re: [PATCH v4 06/12] PCI: Introduce pci_rescan_bus()
* Andrew Morton <[email protected]>:
Quoted 32 lines · On Wed, 18 Mar 2009 16:39:56 -0600 Alex Chiang <[email protected]> wrote:
Quoted 18 lines
drivers/pci/probe.c +17
-0+/** +* pci_rescan_bus - scan a PCI bus for devices. +* @bus: PCI bus to scan +* +* Scan a PCI bus and child buses for new devices, adds them, +* and enables them. +* +* Returns the max number of subordinate bus discovered. +*/ +unsigned int __devinit pci_rescan_bus (struct pci_bus *bus) +{ +unsigned int max; +struct pci_dev *dev; + + max =pci_scan_child_bus (bus); +list_for_each_entry (dev, &bus->devices, bus_list) + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||drivers/pci/probe.c struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, · line 1224
Quoted 10 lines
drivers/pci/probe.c +10
-0+ dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) +if (dev->subordinate) +pci_bus_size_bridges (dev->subordinate); + +pci_bus_assign_resources (bus); +pci_enable_bridges (bus); +pci_bus_add_devices (bus); + +return max; +}The conspicuous lack of locking for the list walk requires either
Quoted 2 lines
a) documenting or
b) fixing
Ok, will figure out (a) or (b).
Thanks.
/ac
PATCH v4 7/12 PCI: Introduce /sys/bus/pci/rescan
In reply to Alex ChiangThis interface allows the user to force a rescan of all PCI buses in system, and rediscover devices that have been removed earlier.
pci_bus_attrs implementation from Trent Piepho.
Thanks to Vegard Nossum for discovering locking issues with the sysfs interface.
---
Documentation/ABI/testing/sysfs-bus-pci | 9 +++++++++ drivers/pci/pci-driver.c | 1 + drivers/pci/pci-sysfs.c | 29 +++++++++++++++++++++++++++++ drivers/pci/pci.h | 6 ++++++ 4 files changed, 45 insertions(+), 0 deletions(-)
Documentation/ABI/testing/sysfs-bus-pci +9 -0
@@ -41,6 +41,15 @@ Description: for the device and attempt to bind to it. For example: # echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id +What: /sys/bus/pci/rescan +Date: January 2009 +Contact: Linux PCI developers <[email protected]> +Description: + Writing a non-zero value to this attribute will + force a rescan of all PCI buses in the system, and + re-discover previously removed devices. + Depends on CONFIG_HOTPLUG. + What: /sys/bus/pci/devices/.../vpd Date: February 2008 Contact: Ben Hutchings <[email protected]>
drivers/pci/pci-driver.c +1 -0
@@ -973,6 +973,7 @@ struct bus_type pci_bus_type = { .remove = pci_device_remove, .shutdown = pci_device_shutdown, .dev_attrs = pci_dev_attrs, + .bus_attrs = pci_bus_attrs, .pm = PCI_PM_OPS_PTR, };
drivers/pci/pci-sysfs.c +29 -0
@@ -219,6 +219,35 @@ msi_bus_store(struct device *dev, struct device_attribute *attr,return count; } +#ifdef CONFIG_HOTPLUG +static DEFINE_MUTEX (pci_remove_rescan_mutex); +static ssize_t bus_rescan_store (struct bus_type *bus,const char *buf, +size_t count) +{ +unsigned long val; +struct pci_bus *b =NULL ; + +if (strict_strtoul (buf,0 , &val) <0 ) +return -EINVAL ; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + +if (val) { +mutex_lock (&pci_remove_rescan_mutex); +while ((b =pci_find_next_bus (b)) !=NULL ) +pci_rescan_bus (b); +mutex_unlock (&pci_remove_rescan_mutex); + } +return count; +} + +struct bus_attribute pci_bus_attrs[] = { +__ATTR (rescan,S_IWUSR ,NULL , bus_rescan_store), + __ATTR_NULL +}; +#endif +struct device_attribute pci_dev_attrs[] = {__ATTR_RO (resource),__ATTR_RO (vendor),
drivers/pci/pci.h +6 -0
@@ -136,6 +136,12 @@ extern int pcie_mch_quirk;extern struct device_attribute pci_dev_attrs[];extern struct device_attribute dev_attr_cpuaffinity;extern struct device_attribute dev_attr_cpulistaffinity; +#ifdef CONFIG_HOTPLUG +extern struct bus_attribute pci_bus_attrs[]; +#else +#define pci_bus_attrs NULL +#endif +/** * pci_match_one_device - Tell if a PCI device structure has a matching
Re: [PATCH v4 07/12] PCI: Introduce /sys/bus/pci/rescan
Quoted 18 lines · On Wed, 18 Mar 2009 16:40:01 -0600 Alex Chiang <[email protected]> wrote:
drivers/pci/pci-sysfs.c +18
-0+#ifdef CONFIG_HOTPLUG +static DEFINE_MUTEX (pci_remove_rescan_mutex); +static ssize_t bus_rescan_store (struct bus_type *bus,const char *buf, +size_t count) +{ +unsigned long val; +struct pci_bus *b =NULL ; + +if (strict_strtoul (buf,0 , &val) <0 ) +return -EINVAL ; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + +if (val) { +mutex_lock (&pci_remove_rescan_mutex); +while ((b =pci_find_next_bus (b)) !=NULL ) +pci_rescan_bus (b);
drivers/pci/pci-sysfs.c msi_bus_store(struct device *dev, struct device_attribute *attr, · line 249
Quoted 10 lines
drivers/pci/pci-sysfs.c +10
-0+ mutex_unlock(&pci_remove_rescan_mutex); + } +return count; +} + +struct bus_attribute pci_bus_attrs[] = { +__ATTR (rescan,S_IWUSR ,NULL , bus_rescan_store), + __ATTR_NULL +}; +#endif
Why CONFIG_HOTPLUG rather than CONFIG_HOTPLUG_PCI (or similar)?
Re: [PATCH v4 07/12] PCI: Introduce /sys/bus/pci/rescan
* Andrew Morton <[email protected]>:
Quoted 24 lines · On Wed, 18 Mar 2009 16:40:01 -0600 Alex Chiang <[email protected]> wrote:
Quoted 23 lines
drivers/pci/pci-sysfs.c +22
-0+#ifdef CONFIG_HOTPLUG +static DEFINE_MUTEX (pci_remove_rescan_mutex); +static ssize_t bus_rescan_store (struct bus_type *bus,const char *buf, +size_t count) +{ +unsigned long val; +struct pci_bus *b =NULL ; + +if (strict_strtoul (buf,0 , &val) <0 ) +return -EINVAL ; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + +if (val) { +mutex_lock (&pci_remove_rescan_mutex); +while ((b =pci_find_next_bus (b)) !=NULL ) +pci_rescan_bus (b); +mutex_unlock (&pci_remove_rescan_mutex); + } +return count; +}
Quoted 8 lines
drivers/pci/pci-sysfs.c msi_bus_store(struct device *dev, struct device_attribute *attr, · line 249
Quoted 6 lines
drivers/pci/pci-sysfs.c +6
-0+ +struct bus_attribute pci_bus_attrs[] = { +__ATTR (rescan,S_IWUSR ,NULL , bus_rescan_store), + __ATTR_NULL +}; +#endif Why
CONFIG_HOTPLUGrather thanCONFIG_HOTPLUG_PCI(or similar)?
I first started out with CONFIG_HOTPLUG_PCI but then all that stuff got compiled out, and I couldn't figure out why at the time.
I'll go back and try and figure out what's really going on. :-/
Thanks.
/ac
Re: [PATCH v4 07/12] PCI: Introduce /sys/bus/pci/rescan
Quoted 10 lines · Alex Chiang
* Andrew Morton <[email protected]>:
Quoted 8 lines
drivers/pci/pci-sysfs.c msi_bus_store(struct device *dev, struct device_attribute *attr, · line 249
Quoted 6 lines
drivers/pci/pci-sysfs.c +6
-0+ +struct bus_attribute pci_bus_attrs[] = { +__ATTR (rescan,S_IWUSR ,NULL , bus_rescan_store), + __ATTR_NULL +}; +#endif Why
CONFIG_HOTPLUGrather thanCONFIG_HOTPLUG_PCI(or similar)?
Quoted 3 lines
I first started out with
CONFIG_HOTPLUG_PCIbut then all that stuff got compiled out, and I couldn't figure out why at the time.
HOTPLUG_PCI is a subset of HOTPLUG. It gives you support for actual hotplug hardware. The rescan/remove functions don't do anything to hotplug hardware and don't use any code from the pci hotplug core (which is designed to support hotplug hardware). Rescan and remove just need the ability to unbind a driver from device, delete a device and create a new device. Which HOTPLUG gives us.
So, we use HOTPLUG because that's all we need. The idea is to make the sysfs interface for PCI have the most features it can support.
If we wanted to make the interface not have remove/rescan unless needed, then using HOTPLUG_PCI wouldn't make much sense. It would be better to have a new option "PCI remove/rescan sysfs interface" or something that turned it on. But it isn't much code, so I don't think it's necessary to do that.
Re: [PATCH v4 07/12] PCI: Introduce /sys/bus/pci/rescan
* Trent Piepho <[email protected]>:
Quoted 25 lines · Alex Chiang
Quoted 11 lines
* Andrew Morton <[email protected]>:
Quoted 6 lines
Quoted 3 lines
+ +struct
bus_attributepci_bus_attrs[] = { +__ATTR(rescan, S_IWUSR, NULL, bus_rescan_store), +__ATTR_NULL+}; +#endifWhy
CONFIG_HOTPLUGrather thanCONFIG_HOTPLUG_PCI(or similar)?I first started out with
CONFIG_HOTPLUG_PCIbut then all that stuff got compiled out, and I couldn't figure out why at the time.
HOTPLUG_PCIis a subset of HOTPLUG. It gives you support for actual hotplug hardware. The rescan/remove functions don't do anything to hotplug hardware and don't use any code from the pci hotplug core (which is designed to support hotplug hardware). Rescan and remove just need the ability to unbind a driver from device, delete a device and create a new device. Which HOTPLUG gives us.So, we use HOTPLUG because that's all we need. The idea is to make the sysfs interface for PCI have the most features it can support.
Quoted 5 lines
If we wanted to make the interface not have remove/rescan unless needed, then using
HOTPLUG_PCIwouldn't make much sense. It would be better to have a new option "PCI remove/rescan sysfs interface" or something that turned it on. But it isn't much code, so I don't think it's necessary to do that.
Well, I don't know what I did wrong last time, but I no longer have technical difficulty putting it under CONFIG_HOTPLUG_PCI.
Looking at Documentation/PCI/pci.txt, and the various archs, it seems they all assume CONFIG_HOTPLUG means PCI.
This could be cleaned up, but it's certainly non-trivial, and a bit more than I'd want to bite off for this particular patchset.
Plus, Trent is right. Looks like we use HOTPLUG_PCI to really mean physically supported hotplug, not the logical stuff that this patchset is adding.
Thanks.
/ac
PATCH v4 8/12 PCI: Introduce /sys/bus/pci/devices/.../remove
In reply to Alex ChiangThis patch adds an attribute named "remove" to a PCI device's sysfs directory. Writing a non-zero value to this attribute will remove the PCI device and any children of it.
Trent Piepho wrote the original implementation and documentation.
Thanks to Vegard Nossum for testing under kmemcheck and finding locking issues with the sysfs interface.
---
Documentation/ABI/testing/sysfs-bus-pci | 8 ++++++ Documentation/filesystems/sysfs-pci.txt | 10 +++++++ drivers/pci/pci-sysfs.c | 44 +++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 0 deletions(-)
Documentation/ABI/testing/sysfs-bus-pci +8 -0
@@ -50,6 +50,14 @@ Description: re-discover previously removed devices. Depends on CONFIG_HOTPLUG. +What: /sys/bus/pci/devices/.../remove +Date: January 2009 +Contact: Linux PCI developers <[email protected]> +Description: + Writing a non-zero value to this attribute will + hot-remove the PCI device and any of its children. + Depends on CONFIG_HOTPLUG. + What: /sys/bus/pci/devices/.../vpd Date: February 2008 Contact: Ben Hutchings <[email protected]>
Documentation/filesystems/sysfs-pci.txt +10 -0
@@ -12,6 +12,7 @@ that support it. For example, a given bus might look like this: | |-- enable | |-- irq | |-- local_cpus + | |-- remove | |-- resource | |-- resource0 | |-- resource1
@@ -36,6 +37,7 @@ files, each with their own function. enable Whether the device is enabled (ascii, rw) irq IRQ number (ascii, ro) local_cpus nearby CPU mask (cpumask, ro) + remove remove device from kernel's list (ascii, wo) resource PCI resource host addresses (ascii, ro) resource0..N PCI resource N, if present (binary, mmap) resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)
@@ -46,6 +48,7 @@ files, each with their own function. ro - read only file rw - file is readable and writable + wo - write only file mmap - file is mmapable ascii - file contains ascii text binary - file contains binary data
@@ -73,6 +76,13 @@ that the device must be enabled for a rom read to return data succesfully. In the event a driver is not bound to the device, it can be enabled using the 'enable' file, documented above. +The 'remove' file is used to remove the PCI device, by writing a non-zero +integer to the file. This does not involve any kind of hot-plug functionality, +e.g. powering off the device. The device is removed from the kernel's list of +PCI devices, the sysfs directory for it is removed, and the device will be +removed from any drivers attached to it. Removal of PCI root buses is +disallowed. + Accessing legacy resources through sysfs ----------------------------------------
drivers/pci/pci-sysfs.c +44 -0
56 lines not on this page · raw message
Re: [PATCH v4 08/12] PCI: Introduce /sys/bus/pci/devices/.../remove
Quoted 49 lines · On Wed, 18 Mar 2009 16:40:06 -0600 Alex Chiang <[email protected]> wrote:
This patch adds an attribute named "remove" to a PCI device's sysfs directory. Writing a non-zero value to this attribute will remove the PCI device and any children of it.
Trent Piepho wrote the original implementation and documentation.
Thanks to Vegard Nossum for testing under kmemcheck and finding locking issues with the sysfs interface.
...
drivers/pci/pci-sysfs.c +32
-0@@ -246,6 +246,47 @@ struct bus_attribute pci_bus_attrs[] = {__ATTR (rescan,S_IWUSR ,NULL , bus_rescan_store), __ATTR_NULL }; + +static void remove_callback (struct device *dev) +{ +int bridge =0 ; +struct pci_dev *pdev =to_pci_dev (dev); + +mutex_lock (&pci_remove_rescan_mutex); + +if (pdev->subordinate) + bridge =1 ; + +pci_remove_bus_device (pdev); +if (bridge &&list_empty (&pdev->bus->devices)) +pci_remove_bus (pdev->bus); + +mutex_unlock (&pci_remove_rescan_mutex); +} + +static ssize_t +remove_store (struct device *dev,struct device_attribute *dummy, +const char *buf,size_t count) +{ +int ret =0 ; +unsigned long val; +struct pci_dev *pdev =to_pci_dev (dev); + +if (strict_strtoul (buf,0 , &val) <0 ) +return -EINVAL ; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; +
drivers/pci/pci-sysfs.c struct bus_attribute pci_bus_attrs[] = { · line 290
Quoted 10 lines
drivers/pci/pci-sysfs.c +9
-0+if (pdev->subordinate &&pci_is_root_bus (pdev->bus)) +return -EBUSY ; + +if (val) + ret =device_schedule_callback (dev, remove_callback); +if (ret) + count = ret; + return count; +}#endif
It is very hard for the reader (this one at least) to work out why device_schedule_callback() is used here, instead of simply doing the work directly.
The way to solve that problem is to add a code comment.
Given that we're in a sysfs write() handler where no relevant locks at all are held, it seems rather weird that we cannot perform this operation synchronously, but no doubt the comment will explain all of this.
Do we need the CAP_SYS_ADMIN check if the sysfs file permissions are correct? (I keep on asking this then forgetting the answer).
The device_schedule_callback() thing exposes us to (I assume) a pile of races, the most obvious of which is "what locking or refcounting keeps *dev alive?". It would be nice to see an analysis/description of the lifetime issues here. Perhaps in the changelog, preferably in code comments.
Re: [PATCH v4 08/12] PCI: Introduce /sys/bus/pci/devices/.../remove
Quoted 66 lines · Andrew Morton
Quoted 49 lines · On Wed, 18 Mar 2009 16:40:06 -0600 Alex Chiang <[email protected]> wrote:
This patch adds an attribute named "remove" to a PCI device's sysfs directory. Writing a non-zero value to this attribute will remove the PCI device and any children of it.
Trent Piepho wrote the original implementation and documentation.
Thanks to Vegard Nossum for testing under kmemcheck and finding locking issues with the sysfs interface.
...
drivers/pci/pci-sysfs.c +32
-0@@ -246,6 +246,47 @@ struct bus_attribute pci_bus_attrs[] = {__ATTR (rescan,S_IWUSR ,NULL , bus_rescan_store), __ATTR_NULL }; + +static void remove_callback (struct device *dev) +{ +int bridge =0 ; +struct pci_dev *pdev =to_pci_dev (dev); + +mutex_lock (&pci_remove_rescan_mutex); + +if (pdev->subordinate) + bridge =1 ; + +pci_remove_bus_device (pdev); +if (bridge &&list_empty (&pdev->bus->devices)) +pci_remove_bus (pdev->bus); + +mutex_unlock (&pci_remove_rescan_mutex); +} + +static ssize_t +remove_store (struct device *dev,struct device_attribute *dummy, +const char *buf,size_t count) +{ +int ret =0 ; +unsigned long val; +struct pci_dev *pdev =to_pci_dev (dev); + +if (strict_strtoul (buf,0 , &val) <0 ) +return -EINVAL ; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; +drivers/pci/pci-sysfs.c struct bus_attribute pci_bus_attrs[] = { · line 290
Quoted 10 lines
drivers/pci/pci-sysfs.c +9
-0+if (pdev->subordinate &&pci_is_root_bus (pdev->bus)) +return -EBUSY ; + +if (val) + ret =device_schedule_callback (dev, remove_callback); +if (ret) + count = ret; + return count; +}#endif It is very hard for the reader (this one at least) to work out why
device_schedule_callback()is used here, instead of simply doing the work directly.
Quoted 8 lines
The way to solve that problem is to add a code comment.
Given that we're in a sysfs
write()handler where no relevant locks at all are held, it seems rather weird that we cannot perform this operation synchronously, but no doubt the comment will explain all of this.Do we need the
CAP_SYS_ADMINcheck if the sysfs file permissions are correct? (I keep on asking this then forgetting the answer).
You can do this kind of check if you want to be paranoid. You can specify the mode of the file when you create it, but if a properly permissive user (like root) changes the mode, it sticks, so that a "normal" use could then write to the file.
Usually I wouldn't recommend checking, as it's overkill if you set the mode properly in the code.
thanks,
greg k-h
Re: [PATCH v4 08/12] PCI: Introduce /sys/bus/pci/devices/.../remove
In reply to Andrew Morton* Andrew Morton <[email protected]>:
Quoted 66 lines · On Wed, 18 Mar 2009 16:40:06 -0600 Alex Chiang <[email protected]> wrote:
Quoted 50 lines
This patch adds an attribute named "remove" to a PCI device's sysfs directory. Writing a non-zero value to this attribute will remove the PCI device and any children of it.
Trent Piepho wrote the original implementation and documentation.
Thanks to Vegard Nossum for testing under kmemcheck and finding locking issues with the sysfs interface.
...
drivers/pci/pci-sysfs.c +32
-0@@ -246,6 +246,47 @@ struct bus_attribute pci_bus_attrs[] = {__ATTR (rescan,S_IWUSR ,NULL , bus_rescan_store), __ATTR_NULL }; + +static void remove_callback (struct device *dev) +{ +int bridge =0 ; +struct pci_dev *pdev =to_pci_dev (dev); + +mutex_lock (&pci_remove_rescan_mutex); + +if (pdev->subordinate) + bridge =1 ; + +pci_remove_bus_device (pdev); +if (bridge &&list_empty (&pdev->bus->devices)) +pci_remove_bus (pdev->bus); + +mutex_unlock (&pci_remove_rescan_mutex); +} + +static ssize_t +remove_store (struct device *dev,struct device_attribute *dummy, +const char *buf,size_t count) +{ +int ret =0 ; +unsigned long val; +struct pci_dev *pdev =to_pci_dev (dev); + +if (strict_strtoul (buf,0 , &val) <0 ) +return -EINVAL ; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; +drivers/pci/pci-sysfs.c struct bus_attribute pci_bus_attrs[] = { · line 290
Quoted 10 lines
drivers/pci/pci-sysfs.c +9
-0+if (pdev->subordinate &&pci_is_root_bus (pdev->bus)) +return -EBUSY ; + +if (val) + ret =device_schedule_callback (dev, remove_callback); +if (ret) + count = ret; + return count; +}#endif It is very hard for the reader (this one at least) to work out why
device_schedule_callback()is used here, instead of simply doing the work directly.
Quoted 1 line
The way to solve that problem is to add a code comment.
Hm, I thought it was well-known that a sysfs attribute cannot remove itself without deadlocking. Thus, we need to use this callback mechanism.
This thread has the most recent discussion:
http://thread.gmane.org/gmane.linux.kernel/805033
I will add a comment to the code.
Quoted 6 lines
Given that we're in a sysfs
write()handler where no relevant locks at all are held, it seems rather weird that we cannot perform this operation synchronously, but no doubt the comment will explain all of this.Do we need the
CAP_SYS_ADMINcheck if the sysfs file permissions are correct? (I keep on asking this then forgetting the answer).
I will remove this (as per Greg's advice in a later mail).
Quoted 5 lines
The
device_schedule_callback()thing exposes us to (I assume) a pile of races, the most obvious of which is "what locking or refcounting keeps *dev alive?". It would be nice to see an analysis/description of the lifetime issues here. Perhaps in the changelog, preferably in code comments.
No races; device_schedule_callback() takes a ref on dev, pinning it until the callback handler returns, after which it releases the ref. You can see this in sysfs_schedule_callback.
Thanks for the review.
/ac
Re: [PATCH v4 08/12] PCI: Introduce /sys/bus/pci/devices/.../remove
In reply to Alex ChiangQuoted 91 lines · Alex Chiang
This patch adds an attribute named "remove" to a PCI device's sysfs directory. Writing a non-zero value to this attribute will remove the PCI device and any children of it.
Trent Piepho wrote the original implementation and documentation.
Thanks to Vegard Nossum for testing under kmemcheck and finding locking issues with the sysfs interface.
Cc Trent Piepho <[email protected]>Signed-off-by Alex Chiang <[email protected]>---
Documentation/ABI/testing/sysfs-bus-pci | 8 ++++++ Documentation/filesystems/sysfs-pci.txt | 10 +++++++ drivers/pci/pci-sysfs.c | 44 +++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 0 deletions(-)Documentation/ABI/testing/sysfs-bus-pci +8
-0@@ -50,6 +50,14 @@ Description: re-discover previously removed devices. Depends on CONFIG_HOTPLUG. +What: /sys/bus/pci/devices/.../remove +Date: January 2009 +Contact: Linux PCI developers <[email protected]> +Description: + Writing a non-zero value to this attribute will + hot-remove the PCI device and any of its children. + Depends on CONFIG_HOTPLUG. + What: /sys/bus/pci/devices/.../vpd Date: February 2008 Contact: Ben Hutchings <[email protected]>Documentation/filesystems/sysfs-pci.txt +10
-0@@ -12,6 +12,7 @@ that support it. For example, a given bus might look like this: | |-- enable | |-- irq | |-- local_cpus + | |-- remove | |-- resource | |-- resource0 | |-- resource1@@ -36,6 +37,7 @@ files, each with their own function. enable Whether the device is enabled (ascii, rw) irq IRQ number (ascii, ro) local_cpus nearby CPU mask (cpumask, ro) + remove remove device from kernel's list (ascii, wo) resource PCI resource host addresses (ascii, ro) resource0..N PCI resource N, if present (binary, mmap) resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)@@ -46,6 +48,7 @@ files, each with their own function. ro - read only file rw - file is readable and writable + wo - write only file mmap - file is mmapable ascii - file contains ascii text binary - file contains binary data@@ -73,6 +76,13 @@ that the device must be enabled for a rom read to return data succesfully. In the event a driver is not bound to the device, it can be enabled using the 'enable' file, documented above. +The 'remove' file is used to remove the PCI device, by writing a non-zero +integer to the file. This does not involve any kind of hot-plug functionality, +e.g. powering off the device. The device is removed from the kernel's list of +PCI devices, the sysfs directory for it is removed, and the device will be +removed from any drivers attached to it. Removal of PCI root buses is +disallowed. + Accessing legacy resources through sysfs ----------------------------------------drivers/pci/pci-sysfs.c +4
-0@@ -246,6 +246,47 @@ struct bus_attribute pci_bus_attrs[] = {__ATTR (rescan,S_IWUSR ,NULL , bus_rescan_store), __ATTR_NULL }; + +static void remove_callback (struct device *dev) +{ +int bridge =0 ;
drivers/pci/pci-sysfs.c struct bus_attribute pci_bus_attrs[] = { · line 262
Quoted 10 lines
drivers/pci/pci-sysfs.c +10
-0+struct pci_dev *pdev =to_pci_dev (dev); + +mutex_lock (&pci_remove_rescan_mutex); + +if (pdev->subordinate) + bridge =1 ; + +pci_remove_bus_device (pdev); +if (bridge &&list_empty (&pdev->bus->devices)) +pci_remove_bus (pdev->bus);
I cannot understand the above two lines. Could you explain what it intend?
Thanks,
Kenji Kaneshige
Quoted 47 lines
drivers/pci/pci-sysfs.c +30
-1+ +mutex_unlock (&pci_remove_rescan_mutex); +} + +static ssize_t +remove_store (struct device *dev,struct device_attribute *dummy, +const char *buf,size_t count) +{ +int ret =0 ; +unsigned long val; +struct pci_dev *pdev =to_pci_dev (dev); + +if (strict_strtoul (buf,0 , &val) <0 ) +return -EINVAL ; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + +if (pdev->subordinate &&pci_is_root_bus (pdev->bus)) +return -EBUSY ; + +if (val) + ret =device_schedule_callback (dev, remove_callback); +if (ret) + count = ret; +return count; +}#endif struct device_attribute pci_dev_attrs[] = {@@ -266,6 +307,9 @@ struct device_attribute pci_dev_attrs[] = {__ATTR (broken_parity_status,(S_IRUGO |S_IWUSR ), broken_parity_status_show,broken_parity_status_store),__ATTR (msi_bus,0644 , msi_bus_show, msi_bus_store), +#ifdef CONFIG_HOTPLUG +__ATTR (remove,S_IWUSR ,NULL , remove_store), +#endif __ATTR_NULL, }; --To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 08/12] PCI: Introduce /sys/bus/pci/devices/.../remove
* Kenji Kaneshige <[email protected]>:
Quoted 94 lines
Quoted 93 lines · Alex Chiang
This patch adds an attribute named "remove" to a PCI device's sysfs directory. Writing a non-zero value to this attribute will remove the PCI device and any children of it.
Trent Piepho wrote the original implementation and documentation.
Thanks to Vegard Nossum for testing under kmemcheck and finding locking issues with the sysfs interface.
Cc Trent Piepho <[email protected]>Signed-off-by Alex Chiang <[email protected]>---
Documentation/ABI/testing/sysfs-bus-pci | 8 ++++++ Documentation/filesystems/sysfs-pci.txt | 10 +++++++ drivers/pci/pci-sysfs.c | 44 +++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 0 deletions(-)Documentation/ABI/testing/sysfs-bus-pci +7
-0@@ -50,6 +50,14 @@ Description: re-discover previously removed devices. Depends on CONFIG_HOTPLUG. +What: /sys/bus/pci/devices/.../remove +Date: January 2009 +Contact: Linux PCI developers <[email protected]> +Description: + Writing a non-zero value to this attribute will + hot-remove the PCI device and any of its children. + Depends on CONFIG_HOTPLUG. + What: /sys/bus/pci/devices/.../vpd Date: February 2008 Contact: Ben Hutchings <[email protected]>Documentation/filesystems/sysfs-pci.txt +3
-0@@ -12,6 +12,7 @@ that support it. For example, a given bus might look like this: | |-- enable | |-- irq | |-- local_cpus + | |-- remove | |-- resource | |-- resource0 | |-- resource1@@ -36,6 +37,7 @@ files, each with their own function. enable Whether the device is enabled (ascii, rw) irq IRQ number (ascii, ro) local_cpus nearby CPU mask (cpumask, ro) + remove remove device from kernel's list (ascii, wo) resource PCI resource host addresses (ascii, ro) resource0..N PCI resource N, if present (binary, mmap) resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)@@ -46,6 +48,7 @@ files, each with their own function. ro - read only file rw - file is readable and writable + wo - write only file mmap - file is mmapable ascii - file contains ascii text binary - file contains binary data@@ -73,6 +76,13 @@ that the device must be enabled for a rom read to return data succesfully. In the event a driver is not bound to the device, it can be enabled using the 'enable' file, documented above. +The 'remove' file is used to remove the PCI device, by writing anon-zero
Documentation/filesystems/sysfs-pci.txt +6
-0+integer to the file. This does not involve any kind of hot-plug functionality, +e.g. powering off the device. The device is removed from the kernel's list of +PCI devices, the sysfs directory for it is removed, and the device will be +removed from any drivers attached to it. Removal of PCI root buses is +disallowed. + Accessing legacy resources through sysfs ---------------------------------------- diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.cindex 22dbc65..6e2b1fd 100644
drivers/pci/pci-sysfs.c +9
-0@@ -246,6 +246,47 @@ struct bus_attribute pci_bus_attrs[] = {__ATTR (rescan,S_IWUSR ,NULL , bus_rescan_store), __ATTR_NULL }; + +static void remove_callback (struct device *dev) +{ +int bridge =0 ; +struct pci_dev *pdev =to_pci_dev (dev); + +mutex_lock (&pci_remove_rescan_mutex); + +if (pdev->subordinate)
Quoted 8 lines
drivers/pci/pci-sysfs.c struct bus_attribute pci_bus_attrs[] = { · line 262
Quoted 5 lines
drivers/pci/pci-sysfs.c +5
-0+ bridge =1 ; + +pci_remove_bus_device (pdev); +if (bridge &&list_empty (&pdev->bus->devices)) +pci_remove_bus (pdev->bus);I cannot understand the above two lines. Could you explain what it intend?
If the user says:
echo 1 > /sys/bus/pci/devices/.../remove
And that device is a bridge, then we need to specifically call pci_remove_bus as well, to actually remove the bus itself. Without it, pci_bus_remove_device() will remove all of its children (and subordinate buses) in a depth-first manner, but we will never actually remove the bus that the user specified.
In other words, without it, we will still see the bus in:
/sys/class/pci_bus/...
We only want to remove the bus if it has no children left. I think the check for list_empty(&pdev->bus->devices) might be overkill... I can try taking that bit out and testing again.
Thanks for the review.
/ac
Quoted 52 lines
Thanks,
Kenji KaneshigeQuoted 46 lines
drivers/pci/pci-sysfs.c +30
-1+ +mutex_unlock (&pci_remove_rescan_mutex); +} + +static ssize_t +remove_store (struct device *dev,struct device_attribute *dummy, +const char *buf,size_t count) +{ +int ret =0 ; +unsigned long val; +struct pci_dev *pdev =to_pci_dev (dev); + +if (strict_strtoul (buf,0 , &val) <0 ) +return -EINVAL ; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + +if (pdev->subordinate &&pci_is_root_bus (pdev->bus)) +return -EBUSY ; + +if (val) + ret =device_schedule_callback (dev, remove_callback); +if (ret) + count = ret; +return count; +}#endif struct device_attribute pci_dev_attrs[] = {@@ -266,6 +307,9 @@ struct device_attribute pci_dev_attrs[] = {__ATTR (broken_parity_status,(S_IRUGO |S_IWUSR ), broken_parity_status_show,broken_parity_status_store),__ATTR (msi_bus,0644 , msi_bus_show, msi_bus_store), +#ifdef CONFIG_HOTPLUG +__ATTR (remove,S_IWUSR ,NULL , remove_store), +#endif __ATTR_NULL, }; --To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 08/12] PCI: Introduce /sys/bus/pci/devices/.../remove
Quoted 10 lines · Alex Chiang
* Kenji Kaneshige <[email protected]>:
Quoted 6 lines
drivers/pci/pci-sysfs.c struct bus_attribute pci_bus_attrs[] = { · line 262
Quoted 3 lines
drivers/pci/pci-sysfs.c +3
-0+pci_remove_bus_device (pdev); +if (bridge &&list_empty (&pdev->bus->devices)) +pci_remove_bus (pdev->bus);I cannot understand the above two lines. Could you explain what it intend?
If the user says:
Quoted 7 lines
echo 1 > /sys/bus/pci/devices/.../removeAnd that device is a bridge, then we need to specifically call
pci_remove_busas well, to actually remove the bus itself. Without it,pci_bus_remove_device()will remove all of its children (and subordinate buses) in a depth-first manner, but we will never actually remove the bus that the user specified.
Did this end up being the source of the pci resource assignment warnings that were produced when re-adding a bridge that was removed?
Re: [PATCH v4 08/12] PCI: Introduce /sys/bus/pci/devices/.../remove
* Trent Piepho <[email protected]>:
Quoted 13 lines · Alex Chiang
Quoted 12 lines
* Kenji Kaneshige <[email protected]>:
Quoted 6 lines
drivers/pci/pci-sysfs.c struct bus_attribute pci_bus_attrs[] = { · line 262
Quoted 3 lines
drivers/pci/pci-sysfs.c +3
-0+pci_remove_bus_device (pdev); +if (bridge &&list_empty (&pdev->bus->devices)) +pci_remove_bus (pdev->bus);I cannot understand the above two lines. Could you explain what it intend?
If the user says:
echo 1 > /sys/bus/pci/devices/.../remove
Quoted 8 lines
Quoted 5 lines
And that device is a bridge, then we need to specifically call
pci_remove_busas well, to actually remove the bus itself. Without it,pci_bus_remove_device()will remove all of its children (and subordinate buses) in a depth-first manner, but we will never actually remove the bus that the user specified.Did this end up being the source of the pci resource assignment warnings that were produced when re-adding a bridge that was removed?
I think that was one reason. I found that it was necessary during multiple remove/rescan cycles; after the 2nd rescan, we had a stale pci_bus hanging around that was manifesting itself as a sysfs issue.
The other thing that Kenji found was in pci_setup_bridge(), where we don't want to initialize the BARs if the bridge has already been added.
Thanks.
/ac
Re: [PATCH v4 08/12] PCI: Introduce /sys/bus/pci/devices/.../remove
In reply to Alex ChiangQuoted 105 lines · Alex Chiang
* Kenji Kaneshige <[email protected]>:
Quoted 93 lines
Quoted 92 lines · Alex Chiang
This patch adds an attribute named "remove" to a PCI device's sysfs directory. Writing a non-zero value to this attribute will remove the PCI device and any children of it.
Trent Piepho wrote the original implementation and documentation.
Thanks to Vegard Nossum for testing under kmemcheck and finding locking issues with the sysfs interface.
Cc Trent Piepho <[email protected]>Signed-off-by Alex Chiang <[email protected]>---
Documentation/ABI/testing/sysfs-bus-pci | 8 ++++++ Documentation/filesystems/sysfs-pci.txt | 10 +++++++ drivers/pci/pci-sysfs.c | 44 +++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 0 deletions(-)Documentation/ABI/testing/sysfs-bus-pci +7
-0@@ -50,6 +50,14 @@ Description: re-discover previously removed devices. Depends on CONFIG_HOTPLUG. +What: /sys/bus/pci/devices/.../remove +Date: January 2009 +Contact: Linux PCI developers <[email protected]> +Description: + Writing a non-zero value to this attribute will + hot-remove the PCI device and any of its children. + Depends on CONFIG_HOTPLUG. + What: /sys/bus/pci/devices/.../vpd Date: February 2008 Contact: Ben Hutchings <[email protected]>Documentation/filesystems/sysfs-pci.txt +3
-0@@ -12,6 +12,7 @@ that support it. For example, a given bus might look like this: | |-- enable | |-- irq | |-- local_cpus + | |-- remove | |-- resource | |-- resource0 | |-- resource1@@ -36,6 +37,7 @@ files, each with their own function. enable Whether the device is enabled (ascii, rw) irq IRQ number (ascii, ro) local_cpus nearby CPU mask (cpumask, ro) + remove remove device from kernel's list (ascii, wo) resource PCI resource host addresses (ascii, ro) resource0..N PCI resource N, if present (binary, mmap) resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)@@ -46,6 +48,7 @@ files, each with their own function. ro - read only file rw - file is readable and writable + wo - write only file mmap - file is mmapable ascii - file contains ascii text binary - file contains binary data@@ -73,6 +76,13 @@ that the device must be enabled for a rom read to return data succesfully. In the event a driver is not bound to the device, it can be enabled using the 'enable' file, documented above. +The 'remove' file is used to remove the PCI device, by writing anon-zero
Documentation/filesystems/sysfs-pci.txt +6
-0+integer to the file. This does not involve any kind of hot-plug functionality, +e.g. powering off the device. The device is removed from the kernel's list of +PCI devices, the sysfs directory for it is removed, and the device will be +removed from any drivers attached to it. Removal of PCI root buses is +disallowed. + Accessing legacy resources through sysfs ---------------------------------------- diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.cindex 22dbc65..6e2b1fd 100644
drivers/pci/pci-sysfs.c +8
-0@@ -246,6 +246,47 @@ struct bus_attribute pci_bus_attrs[] = {__ATTR (rescan,S_IWUSR ,NULL , bus_rescan_store), __ATTR_NULL }; + +static void remove_callback (struct device *dev) +{ +int bridge =0 ; +struct pci_dev *pdev =to_pci_dev (dev); + +mutex_lock (&pci_remove_rescan_mutex); +Quoted 8 lines
drivers/pci/pci-sysfs.c struct bus_attribute pci_bus_attrs[] = { · line 262
Quoted 6 lines
drivers/pci/pci-sysfs.c +6
-0+if (pdev->subordinate) + bridge =1 ; + +pci_remove_bus_device (pdev); +if (bridge &&list_empty (&pdev->bus->devices)) +pci_remove_bus (pdev->bus);I cannot understand the above two lines. Could you explain what it intend?
If the user says:
Quoted 8 lines
echo 1 > /sys/bus/pci/devices/.../removeAnd that device is a bridge, then we need to specifically call
pci_remove_busas well, to actually remove the bus itself. Without it,pci_bus_remove_device()will remove all of its children (and subordinate buses) in a depth-first manner, but we will never actually remove the bus that the user specified.
Do you mean user removes bridge device to remove its *primary* bus? It is very strange. I think the bus should be removed when its parent bridge is removed.
Quoted 4 lines
In other words, without it, we will still see the bus in:
/sys/class/pci_bus/...
What is the problem?
Quoted 4 lines
We only want to remove the bus if it has no children left. I think the check for
list_empty(&pdev->bus->devices)might be overkill... I can try taking that bit out and testing again.
I think we don't need the two lines. But if you do that, you need list_empty(&pdev->bus->devices), doesn't it? On the other hand, we must not check 'bridge' in the if statement. Or bus will never be removed when non-bridge device is removed last on the bus.
Again, I think we don't need the two lines. But am I misunderstanding something?
Thanks,
Kenji Kaneshige
Quoted 61 lines
Thanks for the review.
/ac
Quoted 44 lines
Thanks,
Kenji KaneshigeQuoted 40 lines
drivers/pci/pci-sysfs.c +30
-0+ +mutex_unlock (&pci_remove_rescan_mutex); +} + +static ssize_t +remove_store (struct device *dev,struct device_attribute *dummy, +const char *buf,size_t count) +{ +int ret =0 ; +unsigned long val; +struct pci_dev *pdev =to_pci_dev (dev); + +if (strict_strtoul (buf,0 , &val) <0 ) +return -EINVAL ; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + +if (pdev->subordinate &&pci_is_root_bus (pdev->bus)) +return -EBUSY ; + +if (val) + ret =device_schedule_callback (dev, remove_callback); +if (ret) + count = ret; +return count; +}#endif struct device_attribute pci_dev_attrs[] = {@@ -266,6 +307,9 @@ struct device_attribute pci_dev_attrs[] = {__ATTR (broken_parity_status,(S_IRUGO |S_IWUSR ), broken_parity_status_show,broken_parity_status_store),__ATTR (msi_bus,0644 , msi_bus_show, msi_bus_store), +#ifdef CONFIG_HOTPLUG +__ATTR (remove,S_IWUSR ,NULL , remove_store), +#endif __ATTR_NULL, };Quoted 7 lines
Quoted 6 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 08/12] PCI: Introduce /sys/bus/pci/devices/.../remove
* Kenji Kaneshige <[email protected]>:
Quoted 31 lines
Quoted 21 lines · Alex Chiang
* Kenji Kaneshige <[email protected]>:
Quoted 17 lines
Quoted 4 lines · Alex Chiang
drivers/pci/pci-sysfs.c +4
-0+ +static void remove_callback (struct device *dev) +{ +int bridge =0 ;drivers/pci/pci-sysfs.c struct bus_attribute pci_bus_attrs[] = { · line 262
Quoted 10 lines
drivers/pci/pci-sysfs.c +10
-0+struct pci_dev *pdev =to_pci_dev (dev); + +mutex_lock (&pci_remove_rescan_mutex); + +if (pdev->subordinate) + bridge =1 ; + +pci_remove_bus_device (pdev); +if (bridge &&list_empty (&pdev->bus->devices)) +pci_remove_bus (pdev->bus);I cannot understand the above two lines. Could you explain what it intend?
If the user says:
Quoted 8 lines
echo 1 > /sys/bus/pci/devices/.../removeAnd that device is a bridge, then we need to specifically call
pci_remove_busas well, to actually remove the bus itself. Without it,pci_bus_remove_device()will remove all of its children (and subordinate buses) in a depth-first manner, but we will never actually remove the bus that the user specified.
Quoted 3 lines
Do you mean user removes bridge device to remove its *primary* bus? It is very strange. I think the bus should be removed when its parent bridge is removed.
You are correct.
Quoted 12 lines
Quoted 4 lines
In other words, without it, we will still see the bus in:
/sys/class/pci_bus/...What is the problem?
Quoted 4 lines
We only want to remove the bus if it has no children left. I think the check for
list_empty(&pdev->bus->devices)might be overkill... I can try taking that bit out and testing again.
Quoted 8 lines
I think we don't need the two lines. But if you do that, you need
list_empty(&pdev->bus->devices), doesn't it? On the other hand, we must not check 'bridge' in the if statement. Or bus will never be removed when non-bridge device is removed last on the bus.Again, I think we don't need the two lines. But am I misunderstanding something?
No, you are correct.
I think what was happening was that I inserted that code before I discovered the double-free in the PCIe port driver, and that extra call to pci_remove_bus() helped mask the double-free.
I re-tested again tonight with the port driver fix, and also removing the two lines you mention, and it is behaving correctly.
As always, thanks for your review.
/ac
PATCH v4 9/12 PCI: Introduce /sys/bus/pci/devices/.../rescan
In reply to Alex ChiangThis interface allows the user to force a rescan of the device's parent bus and all subordinate buses, and rediscover devices removed earlier from this part of the device tree.
---
Documentation/ABI/testing/sysfs-bus-pci | 10 ++++++++++ drivers/pci/pci-sysfs.c | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 0 deletions(-)
Documentation/ABI/testing/sysfs-bus-pci +10 -0
@@ -58,6 +58,16 @@ Description: hot-remove the PCI device and any of its children. Depends on CONFIG_HOTPLUG. +What: /sys/bus/pci/devices/.../rescan +Date: January 2009 +Contact: Linux PCI developers <[email protected]> +Description: + Writing a non-zero value to this attribute will + force a rescan of the device's parent bus and all + child buses, and re-discover devices removed earlier + from this part of the device tree. + Depends on CONFIG_HOTPLUG. + What: /sys/bus/pci/devices/.../vpd Date: February 2008 Contact: Ben Hutchings <[email protected]>
drivers/pci/pci-sysfs.c +22 -0
@@ -247,6 +247,27 @@ struct bus_attribute pci_bus_attrs[] = { __ATTR_NULL }; +static ssize_t +dev_rescan_store (struct device *dev,struct device_attribute *attr, +const char *buf,size_t count) +{ +unsigned long val; +struct pci_dev *pdev =to_pci_dev (dev); + +if (strict_strtoul (buf,0 , &val) <0 ) +return -EINVAL ; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + +if (val) { +mutex_lock (&pci_remove_rescan_mutex); +pci_rescan_bus (pdev->bus); +mutex_unlock (&pci_remove_rescan_mutex); + } +return count; +} +static void remove_callback (struct device *dev) {int bridge =0 ;
@@ -309,6 +330,7 @@ struct device_attribute pci_dev_attrs[] = { __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),#ifdef CONFIG_HOTPLUG __ATTR (remove,S_IWUSR ,NULL , remove_store), +__ATTR (rescan,S_IWUSR ,NULL , dev_rescan_store), #endif __ATTR_NULL, };
PATCH v4 10/12 PCI Hotplug: restore fakephp interface with complete reimplementation
In reply to Alex ChiangFrom: Trent Piepho <[email protected]>
A complete re-implementation of fakephp is necessary if it is to present its former interface (pre-2.6.27, when it broke). The reason is that PCI hotplug drivers call pci_hp_register(), which enforces the rule that only one /sys/bus/pci/slots/ file may be created per physical slot.
The change breaks the old fakephp's assumption that it could create a file per function. So we re-implement fakephp to avoid using the standard PCI hotplug API so that we can restore the old fakephp user interface.
It puts entries in /sys/bus/pci/slots with the names of all PCI devices/functions, exactly symmetrical to what is shown in /sys/bus/pci/devices. Each slots/ entry has a "power" attribute, which works the same way as the fakephp driver's power attribute has worked.
There are a few improvements over old fakephp, which couldn't handle PCI devices being added or removed via a means outside of fakephp's knowledge. If a device was added another way, old fakephp didn't notice and didn't create the fake slot for it. If a device was removed another way, old fakephp didn't delete the fake slot for it (and accessing the stale slot caused an oops).
The new implementation overcomes these limitations. As a consequence, removing a bridge with other devices behind it now works as well, which is something else old fakephp couldn't do previously.
This duplicates a tiny bit of the code in the PCI core that does this same function. Re-using that code ends up being more complex than duplicating it, and it makes code in the PCI core more ugly just to support this legacy fakephp interface compatibility layer.
---
drivers/pci/hotplug/Makefile | 2 drivers/pci/hotplug/fakephp.c | 395 ---------------------------------- drivers/pci/hotplug/legacy_fakephp.c | 162 ++++++++++++++ 3 files changed, 163 insertions(+), 396 deletions(-) delete mode 100644 drivers/pci/hotplug/fakephp.c create mode 100644 drivers/pci/hotplug/legacy_fakephp.c
drivers/pci/hotplug/Makefile +1 -1
@@ -20,7 +20,7 @@ obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o # Link this last so it doesn't claim devices that have a real hotplug driver -obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o +obj-$(CONFIG_HOTPLUG_PCI_FAKE) += legacy_fakephp.o pci_hotplug-objs := pci_hotplug_core.o
drivers/pci/hotplug/fakephp.c deleted +0 -395
395 lines not on this page · raw message
drivers/pci/hotplug/legacy_fakephp.c new file +162 -0
162 lines not on this page · raw message
Re: [PATCH v4 10/12] PCI Hotplug: restore fakephp interface with complete reimplementation
Quoted 2 lines · On Wed, 18 Mar 2009 16:40:16 -0600 Alex Chiang <[email protected]> wrote:
A complete re-implementation of fakephp is necessary if it is to present its former interface (pre-2.6.27, when it broke).
We broke an existing interface? wtf?
If it's been broken for this long then do we actually need to resurrect it?
If so, do we need to resurrect it in its old form? This would appear to be an opportunity to improve that interface, unless the old one was perfect?
Re: [PATCH v4 10/12] PCI Hotplug: restore fakephp interface with complete reimplementation
* Andrew Morton <[email protected]>:
Quoted 6 lines · On Wed, 18 Mar 2009 16:40:16 -0600 Alex Chiang <[email protected]> wrote:
Quoted 3 lines
A complete re-implementation of fakephp is necessary if it is to present its former interface (pre-2.6.27, when it broke).
We broke an existing interface? wtf?
When I introduced physical PCI slots in 2.6.27, one of the changes was that the interface we presented in /sys/bus/pci/slots/ was supposed to represent _physical_ slots only.
Before the change, fakephp "abused" that directory by presenting all the PCI devices, independent of any notions of physical slots.
No one thought much of changing what fakephp did during review because we thought it was a developer/debug feature only. After the change, instead of presenting a PCI bus address in sysfs, fakephp present something like "fake%d" where %d is the order that we discovered the device.
The thought process was that, "this is a debug feature only, so let's make it more obvious".
This was an incorrect assumption, it turns out. :(
People like embedded were using it for various things, and it was also the only way to remove (and rediscover) PCI devices (if they weren't supported by platform hotplug).
You can read the thread here:
http://thread.gmane.org/gmane.linux.kernel/761944
The interesting stuff starts in the middle.
Quoted 2 lines
If it's been broken for this long then do we actually need to resurrect it?
This entire patch series is about fixing the mess that I helped create. At the time, it was indicated that there was existing software that depended on finding 2.6.26-style (and older) fakephp stuff in /sys/bus/pci/slots/
After some discussion, we thought it would be better for the functionality to live in the new sysfs interfaces I'm introducing in this series.
The legacy fakephp stuff is to help transition existing software.
Since the only use case of existing software that I know of is in embedded, I think their workaround was to not move to 2.6.27.
Quoted 3 lines
If so, do we need to resurrect it in its old form? This would appear to be an opportunity to improve that interface, unless the old one was perfect?
Well, the goal is to get people away from fakephp completely and move them to these new interfaces. The legacy fakephp stuff is just a transition aid.
Thanks.
/ac
Re: [PATCH v4 10/12] PCI Hotplug: restore fakephp interface with complete reimplementation
In reply to Andrew MortonQuoted 9 lines · Andrew Morton
Quoted 2 lines · On Wed, 18 Mar 2009 16:40:16 -0600 Alex Chiang <[email protected]> wrote:
A complete re-implementation of fakephp is necessary if it is to present its former interface (pre-2.6.27, when it broke).
We broke an existing interface? wtf?
If it's been broken for this long then do we actually need to resurrect it?
I found out it had been broken several months ago and made some of these patches to fix it, but then lost my motivation for getting them into the kernel.
There are people who use the old fakephp interface. I was one of them. They probably don't update their kernels in production systems and embedded devices very often and haven't discovered the breakage in 2.6.27.
Quoted 3 lines
If so, do we need to resurrect it in its old form? This would appear to be an opportunity to improve that interface, unless the old one was perfect?
That's what I did in my initial patches. I created a new interface with the 'remove' file in the pci device's sysfs directory and the 'rescan' file in /sys/bus/pci. This is the new better interface. legacy_fakephp is a module that provides a compatible interface to the pre-2.6.27 one, though it fixes some bugs with the old one and is overall much less code.
PATCH v4 11/12 PCI Hotplug: rename legacy_fakephp to fakephp
In reply to Alex ChiangWe wanted to replace fakephp wholesale, so rename legacy_fakephp back to fakephp. Yes, this is a silly commit, but it produces a much easier patch to read and review.
---
drivers/pci/hotplug/Makefile | 2 drivers/pci/hotplug/fakephp.c | 162 ++++++++++++++++++++++++++++++++++ drivers/pci/hotplug/legacy_fakephp.c | 162 ---------------------------------- 3 files changed, 163 insertions(+), 163 deletions(-) create mode 100644 drivers/pci/hotplug/fakephp.c delete mode 100644 drivers/pci/hotplug/legacy_fakephp.c
drivers/pci/hotplug/Makefile +1 -1
@@ -20,7 +20,7 @@ obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o # Link this last so it doesn't claim devices that have a real hotplug driver -obj-$(CONFIG_HOTPLUG_PCI_FAKE) += legacy_fakephp.o +obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o pci_hotplug-objs := pci_hotplug_core.o
drivers/pci/hotplug/fakephp.c new file +162 -0
162 lines not on this page · raw message
drivers/pci/hotplug/legacy_fakephp.c deleted +0 -162
162 lines not on this page · raw message
PATCH v4 12/12 PCI Hotplug: schedule fakephp for feature removal
In reply to Alex ChiangNow that the PCI core is capable of function-level remove and rescan as well as bus-level rescan, there's no functional need to keep fakephp anymore.
We keep it around for userspace compatibility reasons, schedule removal in three years.
---
Documentation/feature-removal-schedule.txt | 32 ++++++++++++++++++++++++++++ 1 files changed, 32 insertions(+), 0 deletions(-)
Documentation/feature-removal-schedule.txt +32 -0
@@ -335,3 +335,35 @@ Why: In 2.6.18 the Secmark concept was introduced to replace the "compat_net" Secmark, it is time to deprecate the older mechanism and start the process of removing the old code. Who: Paul Moore <[email protected]> + +--------------------------- + +What: fakephp and associated sysfs files in /sys/bus/pci/slots/ +When: 2011 +Why: In 2.6.27, the semantics of /sys/bus/pci/slots was redefined to + represent a machine's physical PCI slots. The change in semantics + had userspace implications, as the hotplug core no longer allowed + drivers to create multiple sysfs files per physical slot (required + for multi-function devices, e.g.). fakephp was seen as a developer's + tool only, and its interface changed. Too late, we learned that + there were some users of the fakephp interface. + + In 2.6.30, the original fakephp interface was restored. At the same + time, the PCI core gained the ability that fakephp provided, namely + function-level hot-remove and hot-add. + + Since the PCI core now provides the same functionality, exposed in: + + /sys/bus/pci/rescan + /sys/bus/pci/devices/.../remove + /sys/bus/pci/devices/.../rescan + + there is no functional reason to maintain fakephp as well. + + We will keep the existing module so that 'modprobe fakephp' will + present the old /sys/bus/pci/slots/... interface for compatibility, + but users are urged to migrate their applications to the API above. + + After a reasonable transition period, we will remove the legacy + fakephp interface. +Who: Alex Chiang <[email protected]>
Quoted 10 lines · Alex Chiang
We're getting close to the new merge window, and I _think_ this patch series is ready for consideration. Notably:
- multiple rescans/removes of devices with and without bridges
- verified that resource allocation after multiple remove/rescan cycles is the same as what we had during initial boot
- fixes the complete suckage of fakephp (that I created)
- doesn't affect existing hotplug drivers
- tested on x86 and ia64 platforms
Quoted 6 lines
Please review, and consider testing. For testing ease, you can pull from my git branch:
git://git.kernel.org/pub/scm/linux/kernel/git/achiang/pci-hotplug.git branch 'test-20090318' is what you want
I got the following oops when I did
# echo 1 > remove
on the bridge device.
[ 6639.239164] =============================================
[ 6639.239191] [ INFO: possible recursive locking detected ]
[ 6639.239212] 2.6.29-rc8-kk #1
[ 6639.239227] ---------------------------------------------
[ 6639.239243] events/8/60 is trying to acquire lock:
[ 6639.239252] (events){--..}, at: [<ffffffff80257fc0>] flush_workqueue+0x0/0xa0
[ 6639.239252]
[ 6639.239252] but task is already holding lock:
[ 6639.239252] (events){--..}, at: [<ffffffff80257648>] run_workqueue+0x108/0x230
[ 6639.239252]
[ 6639.239252] other info that might help us debug this:
[ 6639.239252] 3 locks held by events/8/60:
[ 6639.239252] #0: (events){--..}, at: [<ffffffff80257648>] run_workqueue+0x108/0x230
[ 6639.239252] #1: (&ss->work){--..}, at: [<ffffffff80257648>] run_workqueue+0x108/0x230
[ 6639.239252] #2: (pci_remove_rescan_mutex){--..}, at: [<ffffffff803c05b9>] remove_callback+0x29/0x80
[ 6639.239252]
[ 6639.239252] stack backtrace:
[ 6639.239252] Pid: 60, comm: events/8 Not tainted 2.6.29-rc8-kk #1
[ 6639.239252] Call Trace:
[ 6639.239252] [<ffffffff8026dfcd>] validate_chain+0xb7d/0x1260
[ 6639.239252] [<ffffffff8026eade>] __lock_acquire+0x42e/0xa40
[ 6639.239252] [<ffffffff8026f148>] lock_acquire+0x58/0x80
[ 6639.239252] [<ffffffff80257fc0>] ? flush_workqueue+0x0/0xa0
[ 6639.239252] [<ffffffff8025800d>] flush_workqueue+0x4d/0xa0
[ 6639.239252] [<ffffffff80257fc0>] ? flush_workqueue+0x0/0xa0
[ 6639.239252] [<ffffffff80258070>] flush_scheduled_work+0x10/0x20
[ 6639.239252] [<ffffffffa0158065>] e1000_remove+0x55/0xfe [e1000e]
[ 6639.239252] [<ffffffff8033ee60>] ? sysfs_schedule_callback_work+0x0/0x50
[ 6639.239252] [<ffffffff803bf7a2>] pci_device_remove+0x32/0x70
[ 6639.239252] [<ffffffff80441409>] __device_release_driver+0x59/0x90
[ 6639.241006] [<ffffffff8044153b>] device_release_driver+0x2b/0x40
[ 6639.241006] [<ffffffff80441036>] bus_remove_device+0xa6/0x120
[ 6639.241006] [<ffffffff8043dacb>] device_del+0x12b/0x190
[ 6639.241006] [<ffffffff8043db56>] device_unregister+0x26/0x70
[ 6639.241006] [<ffffffff803ba529>] pci_stop_dev+0x49/0x60
[ 6639.241006] [<ffffffff803ba670>] pci_remove_bus_device+0x40/0xc0
[ 6639.241006] [<ffffffff803ba71d>] pci_remove_behind_bridge+0x2d/0x50
[ 6639.241006] [<ffffffff803ba64e>] pci_remove_bus_device+0x1e/0xc0
[ 6639.241006] [<ffffffff803c05c8>] remove_callback+0x38/0x80
[ 6639.241006] [<ffffffff8033ee7f>] sysfs_schedule_callback_work+0x1f/0x50
[ 6639.241006] [<ffffffff8025769a>] run_workqueue+0x15a/0x230
[ 6639.241006] [<ffffffff80257648>] ? run_workqueue+0x108/0x230
[ 6639.241006] [<ffffffff8025846f>] worker_thread+0x9f/0x100
[ 6639.241006] [<ffffffff8025bce0>] ? autoremove_wake_function+0x0/0x40
[ 6639.241006] [<ffffffff802583d0>] ? worker_thread+0x0/0x100
[ 6639.241006] [<ffffffff8025b89d>] kthread+0x4d/0x80
[ 6639.241006] [<ffffffff8020d4ba>] child_rip+0xa/0x20
[ 6639.241006] [<ffffffff8020cebc>] ? restore_args+0x0/0x30
[ 6639.241006] [<ffffffff8025b850>] ? kthread+0x0/0x80
[ 6639.241006] [<ffffffff8020d4b0>] ? child_rip+0x0/0x20
[ 6639.283330] e1000e 0000:40:00.0: PCI INT A disabled
[ 6639.324332] e1000e 0000:40:00.1: PCI INT B disabled
[ 6639.325031] aer 0000:2f:04.0:pcie22: unloading service driver aerThanks,
Kenji Kaneshige
Quoted 72 lines
Note, this test branch does contain the small assorted patches in AER and the PCIe portdriver that I fixed along the way, but does not contain the sysfs callback mutex that I introduced to protect myself from Vegard Nossum. ;) If you want to hammer away at the sysfs interface, please apply this patch on top:
http://thread.gmane.org/gmane.linux.kernel/806648What I'm continuing to do:
- investigate converting existing hotplug drivers to use new
pci_rescan_bus()interfaceThanks.
/ac
v3 -> v4:
- protect sysfs interfaces with mutex
- undo changes inpci_do_scan_bus
- introducepci_rescan_businstead
- do not initialize bridges more than oncev2 -> v3:
- properly remove device with internal bridge
- added Kenji Kaneshige'spci_is_root_bus()interface
- dropped whitespace cleanups for another timev1 -> v2:
- incorporated lots of Trent Piepho's work
- beefed uppci_do_scan_busas heavy lifter for rescanning
- small bugfixes folded into earlier patches to get everything working---
Alex Chiang (8):
PCI Hotplug: schedule fakephp for feature removal PCI Hotplug: renamelegacy_fakephpto fakephp
PCI: Introduce/sys/bus/pci/devices/.../rescan
PCI: Introduce/sys/bus/pci/devices/.../remove
PCI: Introduce/sys/bus/pci/rescan
PCI: Introducepci_rescan_bus()
PCI: do not initialize bridges more than once
PCI: always scan child busesKenji Kaneshige (1):
PCI:pci_is_root_bushelperTrent Piepho (3):
PCI Hotplug: restore fakephp interface with complete reimplementation
PCI:pci_scan_slot()returns newly found devices
PCI: don't scan existing devicesDocumentation/ABI/testing/sysfs-bus-pci | 27 ++ Documentation/feature-removal-schedule.txt | 32 ++ Documentation/filesystems/sysfs-pci.txt | 10 + drivers/pci/hotplug/fakephp.c | 443 +++++++--------------------- drivers/pci/pci-driver.c | 1 drivers/pci/pci-sysfs.c | 95 ++++++ drivers/pci/pci.h | 6 drivers/pci/probe.c | 103 ++++--- drivers/pci/setup-bus.c | 3 include/linux/pci.h | 12 + 10 files changed, 358 insertions(+), 374 deletions(-)--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
* Kenji Kaneshige <[email protected]>:
Quoted 18 lines
Quoted 10 lines · Alex Chiang
We're getting close to the new merge window, and I _think_ this patch series is ready for consideration. Notably:
- multiple rescans/removes of devices with and without bridges
- verified that resource allocation after multiple remove/rescan cycles is the same as what we had during initial boot
- fixes the complete suckage of fakephp (that I created)
- doesn't affect existing hotplug drivers
- tested on x86 and ia64 platformsQuoted 6 lines
Please review, and consider testing. For testing ease, you can pull from my git branch:
git://git.kernel.org/pub/scm/linux/kernel/git/achiang/pci-hotplug.git branch 'test-20090318' is what you want
Quoted 5 lines
I got the following oops when I did
# echo 1 > removeon the bridge device.
Hm, this is odd; I did test under lockdep.
I'll try again, thanks for testing and the bug report.
/ac
Quoted 133 lines
[ 6639.239164] ============================================= [ 6639.239191] [ INFO: possible recursive locking detected ] [ 6639.239212] 2.6.29-rc8-kk #1 [ 6639.239227] --------------------------------------------- [ 6639.239243] events/8/60 is trying to acquire lock: [ 6639.239252] (events){--..}, at: [<ffffffff80257fc0>] flush_workqueue+0x0/0xa0 [ 6639.239252] [ 6639.239252] but task is already holding lock: [ 6639.239252] (events){--..}, at: [<ffffffff80257648>] run_workqueue+0x108/0x230 [ 6639.239252] [ 6639.239252] other info that might help us debug this: [ 6639.239252] 3 locks held by events/8/60: [ 6639.239252] #0: (events){--..}, at: [<ffffffff80257648>] run_workqueue+0x108/0x230 [ 6639.239252] #1: (&ss->work){--..}, at: [<ffffffff80257648>] run_workqueue+0x108/0x230 [ 6639.239252] #2: (pci_remove_rescan_mutex){--..}, at: [<ffffffff803c05b9>] remove_callback+0x29/0x80 [ 6639.239252] [ 6639.239252] stack backtrace: [ 6639.239252] Pid: 60, comm: events/8 Not tainted 2.6.29-rc8-kk #1 [ 6639.239252] Call Trace: [ 6639.239252] [<ffffffff8026dfcd>] validate_chain+0xb7d/0x1260 [ 6639.239252] [<ffffffff8026eade>] __lock_acquire+0x42e/0xa40 [ 6639.239252] [<ffffffff8026f148>] lock_acquire+0x58/0x80 [ 6639.239252] [<ffffffff80257fc0>] ? flush_workqueue+0x0/0xa0 [ 6639.239252] [<ffffffff8025800d>] flush_workqueue+0x4d/0xa0 [ 6639.239252] [<ffffffff80257fc0>] ? flush_workqueue+0x0/0xa0 [ 6639.239252] [<ffffffff80258070>] flush_scheduled_work+0x10/0x20 [ 6639.239252] [<ffffffffa0158065>] e1000_remove+0x55/0xfe [e1000e] [ 6639.239252] [<ffffffff8033ee60>] ? sysfs_schedule_callback_work+0x0/0x50 [ 6639.239252] [<ffffffff803bf7a2>] pci_device_remove+0x32/0x70 [ 6639.239252] [<ffffffff80441409>] __device_release_driver+0x59/0x90 [ 6639.241006] [<ffffffff8044153b>] device_release_driver+0x2b/0x40 [ 6639.241006] [<ffffffff80441036>] bus_remove_device+0xa6/0x120 [ 6639.241006] [<ffffffff8043dacb>] device_del+0x12b/0x190 [ 6639.241006] [<ffffffff8043db56>] device_unregister+0x26/0x70 [ 6639.241006] [<ffffffff803ba529>] pci_stop_dev+0x49/0x60 [ 6639.241006] [<ffffffff803ba670>] pci_remove_bus_device+0x40/0xc0 [ 6639.241006] [<ffffffff803ba71d>] pci_remove_behind_bridge+0x2d/0x50 [ 6639.241006] [<ffffffff803ba64e>] pci_remove_bus_device+0x1e/0xc0 [ 6639.241006] [<ffffffff803c05c8>] remove_callback+0x38/0x80 [ 6639.241006] [<ffffffff8033ee7f>] sysfs_schedule_callback_work+0x1f/0x50 [ 6639.241006] [<ffffffff8025769a>] run_workqueue+0x15a/0x230 [ 6639.241006] [<ffffffff80257648>] ? run_workqueue+0x108/0x230 [ 6639.241006] [<ffffffff8025846f>] worker_thread+0x9f/0x100 [ 6639.241006] [<ffffffff8025bce0>] ? autoremove_wake_function+0x0/0x40 [ 6639.241006] [<ffffffff802583d0>] ? worker_thread+0x0/0x100 [ 6639.241006] [<ffffffff8025b89d>] kthread+0x4d/0x80 [ 6639.241006] [<ffffffff8020d4ba>] child_rip+0xa/0x20 [ 6639.241006] [<ffffffff8020cebc>] ? restore_args+0x0/0x30 [ 6639.241006] [<ffffffff8025b850>] ? kthread+0x0/0x80 [ 6639.241006] [<ffffffff8020d4b0>] ? child_rip+0x0/0x20 [ 6639.283330] e1000e 0000:40:00.0: PCI INT A disabled [ 6639.324332] e1000e 0000:40:00.1: PCI INT B disabled [ 6639.325031] aer 0000:2f:04.0:pcie22: unloading service driver aerThanks,
Kenji KaneshigeQuoted 72 lines
Note, this test branch does contain the small assorted patches in AER and the PCIe portdriver that I fixed along the way, but does not contain the sysfs callback mutex that I introduced to protect myself from Vegard Nossum. ;) If you want to hammer away at the sysfs interface, please apply this patch on top:
http://thread.gmane.org/gmane.linux.kernel/806648What I'm continuing to do:
- investigate converting existing hotplug drivers to use new
pci_rescan_bus()interfaceThanks.
/ac
v3 -> v4:
- protect sysfs interfaces with mutex
- undo changes inpci_do_scan_bus
- introducepci_rescan_businstead
- do not initialize bridges more than oncev2 -> v3:
- properly remove device with internal bridge
- added Kenji Kaneshige'spci_is_root_bus()interface
- dropped whitespace cleanups for another timev1 -> v2:
- incorporated lots of Trent Piepho's work
- beefed uppci_do_scan_busas heavy lifter for rescanning
- small bugfixes folded into earlier patches to get everything working---
Alex Chiang (8):
PCI Hotplug: schedule fakephp for feature removal PCI Hotplug: renamelegacy_fakephpto fakephp
PCI: Introduce/sys/bus/pci/devices/.../rescan
PCI: Introduce/sys/bus/pci/devices/.../remove
PCI: Introduce/sys/bus/pci/rescan
PCI: Introducepci_rescan_bus()
PCI: do not initialize bridges more than once
PCI: always scan child busesKenji Kaneshige (1):
PCI:pci_is_root_bushelperTrent Piepho (3):
PCI Hotplug: restore fakephp interface with complete reimplementation
PCI:pci_scan_slot()returns newly found devices
PCI: don't scan existing devicesDocumentation/ABI/testing/sysfs-bus-pci | 27 ++ Documentation/feature-removal-schedule.txt | 32 ++ Documentation/filesystems/sysfs-pci.txt | 10 + drivers/pci/hotplug/fakephp.c | 443 +++++++--------------------- drivers/pci/pci-driver.c | 1 drivers/pci/pci-sysfs.c | 95 ++++++ drivers/pci/pci.h | 6 drivers/pci/probe.c | 103 ++++--- drivers/pci/setup-bus.c | 3 include/linux/pci.h | 12 + 10 files changed, 358 insertions(+), 374 deletions(-)--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
* Kenji Kaneshige <[email protected]>:
Quoted 69 lines
Quoted 10 lines · Alex Chiang
We're getting close to the new merge window, and I _think_ this patch series is ready for consideration. Notably:
- multiple rescans/removes of devices with and without bridges
- verified that resource allocation after multiple remove/rescan cycles is the same as what we had during initial boot
- fixes the complete suckage of fakephp (that I created)
- doesn't affect existing hotplug drivers
- tested on x86 and ia64 platformsQuoted 6 lines
Please review, and consider testing. For testing ease, you can pull from my git branch:
git://git.kernel.org/pub/scm/linux/kernel/git/achiang/pci-hotplug.git branch 'test-20090318' is what you wantI got the following oops when I did
# echo 1 > removeon the bridge device.
[ 6639.239164] ============================================= [ 6639.239191] [ INFO: possible recursive locking detected ] [ 6639.239212] 2.6.29-rc8-kk #1 [ 6639.239227] --------------------------------------------- [ 6639.239243] events/8/60 is trying to acquire lock: [ 6639.239252] (events){--..}, at: [<ffffffff80257fc0>] flush_workqueue+0x0/0xa0 [ 6639.239252] [ 6639.239252] but task is already holding lock: [ 6639.239252] (events){--..}, at: [<ffffffff80257648>] run_workqueue+0x108/0x230 [ 6639.239252] [ 6639.239252] other info that might help us debug this: [ 6639.239252] 3 locks held by events/8/60: [ 6639.239252] #0: (events){--..}, at: [<ffffffff80257648>] run_workqueue+0x108/0x230 [ 6639.239252] #1: (&ss->work){--..}, at: [<ffffffff80257648>] run_workqueue+0x108/0x230 [ 6639.239252] #2: (pci_remove_rescan_mutex){--..}, at: [<ffffffff803c05b9>] remove_callback+0x29/0x80 [ 6639.239252] [ 6639.239252] stack backtrace: [ 6639.239252] Pid: 60, comm: events/8 Not tainted 2.6.29-rc8-kk #1 [ 6639.239252] Call Trace: [ 6639.239252] [<ffffffff8026dfcd>] validate_chain+0xb7d/0x1260 [ 6639.239252] [<ffffffff8026eade>] __lock_acquire+0x42e/0xa40 [ 6639.239252] [<ffffffff8026f148>] lock_acquire+0x58/0x80 [ 6639.239252] [<ffffffff80257fc0>] ? flush_workqueue+0x0/0xa0 [ 6639.239252] [<ffffffff8025800d>] flush_workqueue+0x4d/0xa0 [ 6639.239252] [<ffffffff80257fc0>] ? flush_workqueue+0x0/0xa0 [ 6639.239252] [<ffffffff80258070>] flush_scheduled_work+0x10/0x20 [ 6639.239252] [<ffffffffa0158065>] e1000_remove+0x55/0xfe [e1000e] [ 6639.239252] [<ffffffff8033ee60>] ? sysfs_schedule_callback_work+0x0/0x50 [ 6639.239252] [<ffffffff803bf7a2>] pci_device_remove+0x32/0x70 [ 6639.239252] [<ffffffff80441409>] __device_release_driver+0x59/0x90 [ 6639.241006] [<ffffffff8044153b>] device_release_driver+0x2b/0x40 [ 6639.241006] [<ffffffff80441036>] bus_remove_device+0xa6/0x120 [ 6639.241006] [<ffffffff8043dacb>] device_del+0x12b/0x190 [ 6639.241006] [<ffffffff8043db56>] device_unregister+0x26/0x70 [ 6639.241006] [<ffffffff803ba529>] pci_stop_dev+0x49/0x60 [ 6639.241006] [<ffffffff803ba670>] pci_remove_bus_device+0x40/0xc0 [ 6639.241006] [<ffffffff803ba71d>] pci_remove_behind_bridge+0x2d/0x50 [ 6639.241006] [<ffffffff803ba64e>] pci_remove_bus_device+0x1e/0xc0 [ 6639.241006] [<ffffffff803c05c8>] remove_callback+0x38/0x80 [ 6639.241006] [<ffffffff8033ee7f>] sysfs_schedule_callback_work+0x1f/0x50 [ 6639.241006] [<ffffffff8025769a>] run_workqueue+0x15a/0x230 [ 6639.241006] [<ffffffff80257648>] ? run_workqueue+0x108/0x230 [ 6639.241006] [<ffffffff8025846f>] worker_thread+0x9f/0x100 [ 6639.241006] [<ffffffff8025bce0>] ? autoremove_wake_function+0x0/0x40 [ 6639.241006] [<ffffffff802583d0>] ? worker_thread+0x0/0x100
Quoted 8 lines
[ 6639.241006] [<ffffffff8025b89d>] kthread+0x4d/0x80 [ 6639.241006] [<ffffffff8020d4ba>] child_rip+0xa/0x20 [ 6639.241006] [<ffffffff8020cebc>] ? restore_args+0x0/0x30 [ 6639.241006] [<ffffffff8025b850>] ? kthread+0x0/0x80 [ 6639.241006] [<ffffffff8020d4b0>] ? child_rip+0x0/0x20 [ 6639.283330] e1000e 0000:40:00.0: PCI INT A disabled [ 6639.324332] e1000e 0000:40:00.1: PCI INT B disabled [ 6639.325031] aer 0000:2f:04.0:pcie22: unloading service driver aer
pci_device_remove() calls the driver's ->remove method directly; it shouldn't be messing around with that sysfs callback.
Does this only happen with e1000e devices? Or does it happen on any bridge device?
I am stumped; I've never seen this locking issue before...
Will continue to look, thanks.
/ac
Quoted 10 lines · Alex Chiang
We're getting close to the new merge window, and I _think_ this patch series is ready for consideration. Notably:
- multiple rescans/removes of devices with and without bridges
- verified that resource allocation after multiple remove/rescan cycles is the same as what we had during initial boot
- fixes the complete suckage of fakephp (that I created)
- doesn't affect existing hotplug drivers
- tested on x86 and ia64 platforms
Quoted 6 lines
Please review, and consider testing. For testing ease, you can pull from my git branch:
git://git.kernel.org/pub/scm/linux/kernel/git/achiang/pci-hotplug.git branch 'test-20090318' is what you want
When I rescan the bus even without remove anything, I got the following messages. And enable count of the bridge is incremented every time.
[17240.309096] pci 0000:2d:00.0: BAR 6: bogus alignment [0x0-0x0] flags 0x2 [17240.309135] pcieport-driver 0000:00:01.0: setting latency timer to 64 [17240.309143] pcieport-driver 0000:00:02.0: setting latency timer to 64 [17240.309150] pcieport-driver 0000:14:00.0: setting latency timer to 64 [17240.309159] pcieport-driver 0000:15:00.0: setting latency timer to 64 [17240.309166] pcieport-driver 0000:15:01.0: setting latency timer to 64 [17240.309174] pcieport-driver 0000:15:02.0: setting latency timer to 64 [17240.309182] pci 0000:14:00.3: setting latency timer to 64 [17240.309189] pcieport-driver 0000:00:03.0: setting latency timer to 64 [17240.309198] pcieport-driver 0000:2a:00.0: setting latency timer to 64 [17240.309207] pcieport-driver 0000:2b:02.0: setting latency timer to 64 [17240.309215] pcieport-driver 0000:2b:04.0: setting latency timer to 64 [17240.309223] pcieport-driver 0000:00:04.0: setting latency timer to 64 [17240.309231] pcieport-driver 0000:2e:00.0: setting latency timer to 64 [17240.309240] pcieport-driver 0000:2f:02.0: setting latency timer to 64 [17240.309248] pcieport-driver 0000:2f:04.0: setting latency timer to 64 [17240.309256] pcieport-driver 0000:00:06.0: setting latency timer to 64 [17240.309264] pcieport-driver 0000:51:00.0: setting latency timer to 64 [17240.309273] pcieport-driver 0000:52:02.0: setting latency timer to 64 [17240.309281] pcieport-driver 0000:52:04.0: setting latency timer to 64 [17240.309291] pci 0000:64:00.0: setting latency timer to 64 [17240.309300] pcieport-driver 0000:00:1c.0: setting latency timer to 64 [17240.309308] pci 0000:00:1e.0: setting latency timer to 64
[root@localhost pci]# echo 1 > rescan
[root@localhost pci]# cat /sys/bus/pci/devices/0000\:2f\:04.0/enable 6
[root@localhost pci]# echo 1 > rescan
[root@localhost pci]# cat /sys/bus/pci/devices/0000\:2f\:04.0/enable 7
[root@localhost pci]# echo 1 > rescan
[root@localhost pci]# cat /sys/bus/pci/devices/0000\:2f\:04.0/enable 8
[root@localhost pci]# echo 1 > rescan
[root@localhost pci]# cat /sys/bus/pci/devices/0000\:2f\:04.0/enable 9
Thanks,
Kenji Kaneshige
* Kenji Kaneshige <[email protected]>:
Quoted 37 lines
Quoted 10 lines · Alex Chiang
We're getting close to the new merge window, and I _think_ this patch series is ready for consideration. Notably:
- multiple rescans/removes of devices with and without bridges
- verified that resource allocation after multiple remove/rescan cycles is the same as what we had during initial boot
- fixes the complete suckage of fakephp (that I created)
- doesn't affect existing hotplug drivers
- tested on x86 and ia64 platformsQuoted 6 lines
Please review, and consider testing. For testing ease, you can pull from my git branch:
git://git.kernel.org/pub/scm/linux/kernel/git/achiang/pci-hotplug.git branch 'test-20090318' is what you wantWhen I rescan the bus even without remove anything, I got the following messages. And enable count of the bridge is incremented every time.
[17240.309096] pci 0000:2d:00.0: BAR 6: bogus alignment [0x0-0x0] flags 0x2 [17240.309135] pcieport-driver 0000:00:01.0: setting latency timer to 64 [17240.309143] pcieport-driver 0000:00:02.0: setting latency timer to 64 [17240.309150] pcieport-driver 0000:14:00.0: setting latency timer to 64 [17240.309159] pcieport-driver 0000:15:00.0: setting latency timer to 64 [17240.309166] pcieport-driver 0000:15:01.0: setting latency timer to 64 [17240.309174] pcieport-driver 0000:15:02.0: setting latency timer to 64 [17240.309182] pci 0000:14:00.3: setting latency timer to 64 [17240.309189] pcieport-driver 0000:00:03.0: setting latency timer to 64 [17240.309198] pcieport-driver 0000:2a:00.0: setting latency timer to 64 [17240.309207] pcieport-driver 0000:2b:02.0: setting latency timer to 64 [17240.309215] pcieport-driver 0000:2b:04.0: setting latency timer to 64 [17240.309223] pcieport-driver 0000:00:04.0: setting latency timer to 64 [17240.309231] pcieport-driver 0000:2e:00.0: setting latency timer to 64 [17240.309240] pcieport-driver 0000:2f:02.0: setting latency timer to 64
Quoted 8 lines
[17240.309248] pcieport-driver 0000:2f:04.0: setting latency timer to 64 [17240.309256] pcieport-driver 0000:00:06.0: setting latency timer to 64 [17240.309264] pcieport-driver 0000:51:00.0: setting latency timer to 64 [17240.309273] pcieport-driver 0000:52:02.0: setting latency timer to 64 [17240.309281] pcieport-driver 0000:52:04.0: setting latency timer to 64 [17240.309291] pci 0000:64:00.0: setting latency timer to 64 [17240.309300] pcieport-driver 0000:00:1c.0: setting latency timer to 64 [17240.309308] pci 0000:00:1e.0: setting latency timer to 64
I will investigate these.
Quoted 4 lines
[root@localhost pci]# echo 1 > rescan
[root@localhost pci]# cat /sys/bus/pci/devices/0000\:2f\:04.0/enable 6
[root@localhost pci]# echo 1 > rescan
Quoted 8 lines
[root@localhost pci]# cat /sys/bus/pci/devices/0000\:2f\:04.0/enable 7
[root@localhost pci]# echo 1 > rescan
[root@localhost pci]# cat /sys/bus/pci/devices/0000\:2f\:04.0/enable 8
[root@localhost pci]# echo 1 > rescan
[root@localhost pci]# cat /sys/bus/pci/devices/0000\:2f\:04.0/enable 9
Hm, that's because I'm calling pci_enable_bridges() unconditionally every time even if we didn't add any new bridges, which is obviously wrong.
I will try and figure out a fix for this.
Thanks for testing.
/ac
* Kenji Kaneshige <[email protected]>:
Quoted 18 lines
Quoted 10 lines · Alex Chiang
We're getting close to the new merge window, and I _think_ this patch series is ready for consideration. Notably:
- multiple rescans/removes of devices with and without bridges
- verified that resource allocation after multiple remove/rescan cycles is the same as what we had during initial boot
- fixes the complete suckage of fakephp (that I created)
- doesn't affect existing hotplug drivers
- tested on x86 and ia64 platformsQuoted 6 lines
Please review, and consider testing. For testing ease, you can pull from my git branch:
git://git.kernel.org/pub/scm/linux/kernel/git/achiang/pci-hotplug.git branch 'test-20090318' is what you want
Quoted 5 lines
When I rescan the bus even without remove anything, I got the following messages. And enable count of the bridge is incremented every time.
[17240.309096] pci 0000:2d:00.0: BAR 6: bogus alignment [0x0-0x0] flags 0x2
I'm not sure where this is coming from.
Quoted 23 lines
[17240.309135] pcieport-driver 0000:00:01.0: setting latency timer to 64 [17240.309143] pcieport-driver 0000:00:02.0: setting latency timer to 64 [17240.309150] pcieport-driver 0000:14:00.0: setting latency timer to 64 [17240.309159] pcieport-driver 0000:15:00.0: setting latency timer to 64 [17240.309166] pcieport-driver 0000:15:01.0: setting latency timer to 64 [17240.309174] pcieport-driver 0000:15:02.0: setting latency timer to 64 [17240.309182] pci 0000:14:00.3: setting latency timer to 64 [17240.309189] pcieport-driver 0000:00:03.0: setting latency timer to 64 [17240.309198] pcieport-driver 0000:2a:00.0: setting latency timer to 64 [17240.309207] pcieport-driver 0000:2b:02.0: setting latency timer to 64 [17240.309215] pcieport-driver 0000:2b:04.0: setting latency timer to 64 [17240.309223] pcieport-driver 0000:00:04.0: setting latency timer to 64 [17240.309231] pcieport-driver 0000:2e:00.0: setting latency timer to 64 [17240.309240] pcieport-driver 0000:2f:02.0: setting latency timer to 64 [17240.309248] pcieport-driver 0000:2f:04.0: setting latency timer to 64 [17240.309256] pcieport-driver 0000:00:06.0: setting latency timer to 64 [17240.309264] pcieport-driver 0000:51:00.0: setting latency timer to 64 [17240.309273] pcieport-driver 0000:52:02.0: setting latency timer to 64 [17240.309281] pcieport-driver 0000:52:04.0: setting latency timer to 64 [17240.309291] pci 0000:64:00.0: setting latency timer to 64 [17240.309300] pcieport-driver 0000:00:1c.0: setting latency timer to 64 [17240.309308] pci 0000:00:1e.0: setting latency timer to 64
Quoted 12 lines
[root@localhost pci]# echo 1 > rescan
[root@localhost pci]# cat /sys/bus/pci/devices/0000\:2f\:04.0/enable 6
[root@localhost pci]# echo 1 > rescan
[root@localhost pci]# cat /sys/bus/pci/devices/0000\:2f\:04.0/enable 7
[root@localhost pci]# echo 1 > rescan
[root@localhost pci]# cat /sys/bus/pci/devices/0000\:2f\:04.0/enable 8
[root@localhost pci]# echo 1 > rescan
[root@localhost pci]# cat /sys/bus/pci/devices/0000\:2f\:04.0/enable 9
But the above should be fixed with a new patch that I added today.
Would you mind testing again?
git://git.kernel.org/pub/scm/linux/kernel/git/achiang/pci-hotplug.git test-20090319
I still haven't figured out why you're seeing that recursive lock warning.
Thanks.
/ac