Commit 6441582c authored by Paul Mackerras's avatar Paul Mackerras Committed by Linus Torvalds

[PATCH] ppc64: fix unbalanced dev_get/put calls in EEH code

This patch fixes some unbalanced usage of pci_dev_get()/pci_dev_put() calls
in the eeh code.  The old code had too many calls to dev_put, which could
cause memory structs to be freed prematurely, possibly leading to bad bad
pointer derefs in certain cases.
Signed-off-by: default avatarLinas Vepstas <linas@linas.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 69867f86
...@@ -214,7 +214,6 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev) ...@@ -214,7 +214,6 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
if (!dn) { if (!dn) {
printk(KERN_WARNING "PCI: no pci dn found for dev=%s %s\n", printk(KERN_WARNING "PCI: no pci dn found for dev=%s %s\n",
pci_name(dev), pci_pretty_name(dev)); pci_name(dev), pci_pretty_name(dev));
pci_dev_put(dev);
return; return;
} }
...@@ -225,10 +224,12 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev) ...@@ -225,10 +224,12 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
printk(KERN_INFO "PCI: skip building address cache for=%s %s\n", printk(KERN_INFO "PCI: skip building address cache for=%s %s\n",
pci_name(dev), pci_pretty_name(dev)); pci_name(dev), pci_pretty_name(dev));
#endif #endif
pci_dev_put(dev);
return; return;
} }
/* The cache holds a reference to the device... */
pci_dev_get(dev);
/* Walk resources on this device, poke them into the tree */ /* Walk resources on this device, poke them into the tree */
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
unsigned long start = pci_resource_start(dev,i); unsigned long start = pci_resource_start(dev,i);
...@@ -278,6 +279,8 @@ static inline void __pci_addr_cache_remove_device(struct pci_dev *dev) ...@@ -278,6 +279,8 @@ static inline void __pci_addr_cache_remove_device(struct pci_dev *dev)
} }
n = rb_next(n); n = rb_next(n);
} }
/* The cache no longer holds its reference to this device... */
pci_dev_put(dev); pci_dev_put(dev);
} }
...@@ -317,7 +320,6 @@ void __init pci_addr_cache_build(void) ...@@ -317,7 +320,6 @@ void __init pci_addr_cache_build(void)
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
/* Ignore PCI bridges ( XXX why ??) */ /* Ignore PCI bridges ( XXX why ??) */
if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) { if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
pci_dev_put(dev);
continue; continue;
} }
pci_addr_cache_insert_device(dev); pci_addr_cache_insert_device(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment